Examples: Write your own SynEdit HighLighter

git-svn-id: trunk@35116 -
This commit is contained in:
martin 2012-02-03 19:33:35 +00:00
parent 7a03599f16
commit 0a388b8f9f
8 changed files with 1423 additions and 0 deletions

7
.gitattributes vendored
View File

@ -3356,6 +3356,13 @@ examples/SynEdit/Completion/SynCompletionSample.lpr svneol=native#text/pascal
examples/SynEdit/Completion/SynCompletionSample.res -text
examples/SynEdit/Completion/unit1.lfm svneol=native#text/plain
examples/SynEdit/Completion/unit1.pas svneol=native#text/pascal
examples/SynEdit/NewHighlighterTutorial/HighlighterTutorial.lpi svneol=native#text/xml
examples/SynEdit/NewHighlighterTutorial/HighlighterTutorial.lpr svneol=native#text/pascal
examples/SynEdit/NewHighlighterTutorial/contexthl.pas svneol=native#text/pascal
examples/SynEdit/NewHighlighterTutorial/foldhl.pas svneol=native#text/pascal
examples/SynEdit/NewHighlighterTutorial/simplehl.pas svneol=native#text/pascal
examples/SynEdit/NewHighlighterTutorial/unit1.lfm svneol=native#text/pascal
examples/SynEdit/NewHighlighterTutorial/unit1.pas svneol=native#text/pascal
examples/SynEdit/SynAnyHighlighter/README.txt svneol=native#text/plain
examples/SynEdit/SynAnyHighlighter/synanysynhighlighter.lpi svneol=native#text/plain
examples/SynEdit/SynAnyHighlighter/synanysynhighlighter.lpr svneol=native#text/plain

View File

@ -0,0 +1,115 @@
<?xml version="1.0"?>
<CONFIG>
<ProjectOptions>
<Version Value="9"/>
<PathDelim Value="\"/>
<General>
<SessionStorage Value="InProjectDir"/>
<MainUnit Value="0"/>
<Title Value="project1"/>
<ResourceType Value="res"/>
<UseXPManifest Value="True"/>
<Icon Value="0"/>
</General>
<i18n>
<EnableI18N LFM="False"/>
</i18n>
<VersionInfo>
<StringTable ProductVersion=""/>
</VersionInfo>
<BuildModes Count="1">
<Item1 Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
<IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
<ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/>
</PublishOptions>
<RunParams>
<local>
<FormatVersion Value="1"/>
</local>
</RunParams>
<RequiredPackages Count="2">
<Item1>
<PackageName Value="SynEdit"/>
</Item1>
<Item2>
<PackageName Value="LCL"/>
</Item2>
</RequiredPackages>
<Units Count="5">
<Unit0>
<Filename Value="HighlighterTutorial.lpr"/>
<IsPartOfProject Value="True"/>
<UnitName Value="HighlighterTutorial"/>
</Unit0>
<Unit1>
<Filename Value="unit1.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="Form1"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="Unit1"/>
</Unit1>
<Unit2>
<Filename Value="simplehl.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="SimpleHl"/>
</Unit2>
<Unit3>
<Filename Value="contexthl.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="ContextHL"/>
</Unit3>
<Unit4>
<Filename Value="foldhl.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="FoldHl"/>
</Unit4>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<Target>
<Filename Value="HighlighterTutorial"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir)"/>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<CodeGeneration>
<Checks>
<IOChecks Value="True"/>
<RangeChecks Value="True"/>
<OverflowChecks Value="True"/>
<StackChecks Value="True"/>
</Checks>
</CodeGeneration>
<Linking>
<Debugging>
<DebugInfoType Value="dsDwarf2Set"/>
<UseHeaptrc Value="True"/>
</Debugging>
</Linking>
<Other>
<CompilerMessages>
<UseMsgFile Value="True"/>
</CompilerMessages>
<CompilerPath Value="$(CompPath)"/>
</Other>
</CompilerOptions>
<Debugging>
<Exceptions Count="3">
<Item1>
<Name Value="EAbort"/>
</Item1>
<Item2>
<Name Value="ECodetoolError"/>
</Item2>
<Item3>
<Name Value="EFOpenError"/>
</Item3>
</Exceptions>
</Debugging>
</CONFIG>

View File

@ -0,0 +1,22 @@
program HighlighterTutorial;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Interfaces, // this includes the LCL widgetset
Forms, Unit1, SimpleHl, ContextHL, FoldHl
{ you can add units after this };
{$R *.res}
begin
Application.Title := 'project1';
RequireDerivedFormResource := True;
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.

View File

@ -0,0 +1,82 @@
unit ContextHL;
(*
This is an example how to implement your own highlighter.
This example extends the Simple HL:
- The token -- and ++ (must be surrounded by space or line-begin/end to be
a token of their own) will toggle words that start with a,e,i,o,u
Multply ++ and -- can be nested. Then for each -- a ++ must be given,
before the words highlicht again
See comments below and http://wiki.lazarus.freepascal.org/SynEdit_Highlighter
*)
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Graphics, SynEditTypes, SynEditHighlighter, SimpleHl;
type
{ TSynDemoHlContext }
TSynDemoHlContext = class(TSynDemoHl)
protected
FCurRange: Integer;
public
procedure Next; override;
function GetTokenAttribute: TSynHighlighterAttributes; override;
public
procedure SetRange(Value: Pointer); override;
procedure ResetRange; override;
function GetRange: Pointer; override;
end;
implementation
{ TSynDemoHlContext }
procedure TSynDemoHlContext.Next;
begin
inherited Next;
if (copy(FLineText, FTokenPos, FTokenEnd - FTokenPos) = '--') then
inc(FCurRange);
if (copy(FLineText, FTokenPos, FTokenEnd - FTokenPos) = '++') and (FCurRange > 0) then
dec(FCurRange);
end;
function TSynDemoHlContext.GetTokenAttribute: TSynHighlighterAttributes;
begin
Result := inherited GetTokenAttribute;
if (Result = SpecialAttri) and (FCurRange > 0) then
Result := IdentifierAttribute;
end;
procedure TSynDemoHlContext.SetRange(Value: Pointer);
begin
// Set the current range (for current line)
// The value is provided from an internal storage, where it was kept since the last scan
// This is the and value of the previous line, which is used as start for the new line
FCurRange := PtrInt(Value);
end;
procedure TSynDemoHlContext.ResetRange;
begin
FCurRange := 0;
end;
function TSynDemoHlContext.GetRange: Pointer;
begin
// Get a storable copy of the cuurent (working) range
Result := Pointer(PtrInt(FCurRange));
end;
end.

View File

@ -0,0 +1,316 @@
unit FoldHl;
(*
This is an example how to implement your own highlighter.
This example extends the Simple and Context HL:
- The token -(- and -)- (must be surrounded by space or line-begin/end to be
a token of their own) will add foldable sections
Multply -(- and -)- can be nested.
See comments below and http://wiki.lazarus.freepascal.org/SynEdit_Highlighter
*)
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Graphics, SynEditTypes, SynEditHighlighter, SynEditHighlighterFoldBase, ContextHL;
type
(* This is an EXACT COPY of SynEditHighlighter
ONLY the base class is changed to add support for folding
The new code follows below
*)
TSynDemoHlFoldBase = class(TSynCustomFoldHighlighter)
private
FNotAttri: TSynHighlighterAttributes;
fSpecialAttri: TSynHighlighterAttributes;
fIdentifierAttri: TSynHighlighterAttributes;
fSpaceAttri: TSynHighlighterAttributes;
procedure SetIdentifierAttri(AValue: TSynHighlighterAttributes);
procedure SetNotAttri(AValue: TSynHighlighterAttributes);
procedure SetSpaceAttri(AValue: TSynHighlighterAttributes);
procedure SetSpecialAttri(AValue: TSynHighlighterAttributes);
protected
// accesible for the other examples
FTokenPos, FTokenEnd: Integer;
FLineText: String;
public
procedure SetLine(const NewValue: String; LineNumber: Integer); override;
procedure Next; override;
function GetEol: Boolean; override;
procedure GetTokenEx(out TokenStart: PChar; out TokenLength: integer); override;
function GetTokenAttribute: TSynHighlighterAttributes; override;
public
function GetToken: String; override;
function GetTokenPos: Integer; override;
function GetTokenKind: integer; override;
function GetDefaultAttribute(Index: integer): TSynHighlighterAttributes; override;
constructor Create(AOwner: TComponent); override;
published
(* Define 4 Attributes, for the different highlights. *)
property SpecialAttri: TSynHighlighterAttributes read fSpecialAttri
write SetSpecialAttri;
property NotAttri: TSynHighlighterAttributes read FNotAttri
write SetNotAttri;
property IdentifierAttri: TSynHighlighterAttributes read fIdentifierAttri
write SetIdentifierAttri;
property SpaceAttri: TSynHighlighterAttributes read fSpaceAttri
write SetSpaceAttri;
end;
(* This is a COPY of SynEditHighlighter
ONLY the base class is changed to add support for folding
The new code follows below
*)
TSynDemoHlContextFoldBase = class(TSynDemoHlFoldBase)
protected
FCurRange: Integer;
public
procedure Next; override;
function GetTokenAttribute: TSynHighlighterAttributes; override;
public
(* The below needed to be changed and are in TSynDemoHlFold
TSynDemoHlContextFoldBase uses Ranges itself.
The Range needed here is therefore stored in a diff location
*)
//procedure SetRange(Value: Pointer); override;
//procedure ResetRange; override;
//function GetRange: Pointer; override;
end;
{ TSynDemoHlContext }
(* You can base this on either
TSynDemoHlFoldBase or TSynDemoHlContextFoldBase
Using ranges is NOT a condition for fold.
(If changing, remove Range related code)
Note that ranges to change.
*)
//TSynDemoHlFold = class(TSynDemoHlFoldBase)
TSynDemoHlFold = class(TSynDemoHlContextFoldBase)
public
procedure Next; override;
public
procedure SetRange(Value: Pointer); override;
procedure ResetRange; override;
function GetRange: Pointer; override;
end;
implementation
{ TSynDemoHlFold }
procedure TSynDemoHlFold.Next;
begin
inherited Next;
if (copy(FLineText, FTokenPos, FTokenEnd - FTokenPos) = '-(-') then
StartCodeFoldBlock(nil);
if (copy(FLineText, FTokenPos, FTokenEnd - FTokenPos) = '-)-') then
EndCodeFoldBlock;
end;
procedure TSynDemoHlFold.SetRange(Value: Pointer);
begin
// must call the SetRange in TSynCustomFoldHighlighter
inherited SetRange(Value);
FCurRange := PtrInt(CodeFoldRange.RangeType);
end;
procedure TSynDemoHlFold.ResetRange;
begin
inherited ResetRange;
FCurRange := 0;
end;
function TSynDemoHlFold.GetRange: Pointer;
begin
// Store the range first
CodeFoldRange.RangeType := Pointer(PtrInt(FCurRange));
Result := inherited GetRange;
end;
(* This is an EXACT COPY of SynEditHighlighter
ONLY the base class is changed to add support for folding
*)
constructor TSynDemoHlFoldBase.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
(* Create and initialize the attributes *)
fSpecialAttri := TSynHighlighterAttributes.Create('special', 'special');
AddAttribute(fSpecialAttri);
fSpecialAttri.Style := [fsBold];
FNotAttri := TSynHighlighterAttributes.Create('not', 'not');
AddAttribute(FNotAttri);
FNotAttri.Background := clRed;
fIdentifierAttri := TSynHighlighterAttributes.Create('ident', 'ident');
AddAttribute(fIdentifierAttri);
fSpaceAttri := TSynHighlighterAttributes.Create('space', 'space');
AddAttribute(fSpaceAttri);
fSpaceAttri.FrameColor := clSilver;
fSpaceAttri.FrameEdges := sfeAround;
end;
(* Setters for attributes / This allows using in Object inspector*)
procedure TSynDemoHlFoldBase.SetIdentifierAttri(AValue: TSynHighlighterAttributes);
begin
fIdentifierAttri.Assign(AValue);
end;
procedure TSynDemoHlFoldBase.SetNotAttri(AValue: TSynHighlighterAttributes);
begin
FNotAttri.Assign(AValue);
end;
procedure TSynDemoHlFoldBase.SetSpaceAttri(AValue: TSynHighlighterAttributes);
begin
fSpaceAttri.Assign(AValue);
end;
procedure TSynDemoHlFoldBase.SetSpecialAttri(AValue: TSynHighlighterAttributes);
begin
fSpecialAttri.Assign(AValue);
end;
procedure TSynDemoHlFoldBase.SetLine(const NewValue: String; LineNumber: Integer);
begin
inherited;
FLineText := NewValue;
// Next will start at "FTokenEnd", so set this to 1
FTokenEnd := 1;
Next;
end;
procedure TSynDemoHlFoldBase.Next;
var
l: Integer;
begin
// FTokenEnd should be at the start of the next Token (which is the Token we want)
FTokenPos := FTokenEnd;
// assume empty, will only happen for EOL
FTokenEnd := FTokenPos;
// Scan forward
// FTokenEnd will be set 1 after the last char. That is:
// - The first char of the next token
// - or past the end of line (which allows GetEOL to work)
l := length(FLineText);
If FTokenPos > l then
// At line end
exit
else
if FLineText[FTokenEnd] in [#9, ' '] then
// At Space? Find end of spaces
while (FTokenEnd <= l) and (FLineText[FTokenEnd] in [#0..#32]) do inc (FTokenEnd)
else
// At None-Space? Find end of None-spaces
while (FTokenEnd <= l) and not(FLineText[FTokenEnd] in [#9, ' ']) do inc (FTokenEnd)
end;
function TSynDemoHlFoldBase.GetEol: Boolean;
begin
Result := FTokenPos > length(FLineText);
end;
procedure TSynDemoHlFoldBase.GetTokenEx(out TokenStart: PChar; out TokenLength: integer);
begin
TokenStart := @FLineText[FTokenPos];
TokenLength := FTokenEnd - FTokenPos;
end;
function TSynDemoHlFoldBase.GetTokenAttribute: TSynHighlighterAttributes;
begin
// Match the text, specified by FTokenPos and FTokenEnd
if FLineText[FTokenPos] in [#9, ' '] then
Result := SpaceAttri
else
if LowerCase(FLineText[FTokenPos]) in ['a', 'e', 'i', 'o', 'u'] then
Result := SpecialAttri
else
if LowerCase(copy(FLineText, FTokenPos, FTokenEnd - FTokenPos)) = 'not' then
Result := NotAttri
else
Result := IdentifierAttri;
end;
function TSynDemoHlFoldBase.GetToken: String;
begin
Result := copy(FLineText, FTokenPos, FTokenEnd - FTokenPos);
end;
function TSynDemoHlFoldBase.GetTokenPos: Integer;
begin
Result := FTokenPos - 1;
end;
function TSynDemoHlFoldBase.GetDefaultAttribute(Index: integer): TSynHighlighterAttributes;
begin
// Some default attributes
case Index of
SYN_ATTR_COMMENT: Result := fSpecialAttri;
SYN_ATTR_IDENTIFIER: Result := fIdentifierAttri;
SYN_ATTR_WHITESPACE: Result := fSpaceAttri;
else Result := nil;
end;
end;
function TSynDemoHlFoldBase.GetTokenKind: integer;
var
a: TSynHighlighterAttributes;
begin
// Map Attribute into a unique number
a := GetTokenAttribute;
Result := 0;
if a = fSpaceAttri then Result := 1;
if a = fSpecialAttri then Result := 2;
if a = fIdentifierAttri then Result := 3;
if a = FNotAttri then Result := 4;
end;
(* This is an EXACT COPY of SynEditHighlighter
ONLY the base class is changed to add support for folding
*)
procedure TSynDemoHlContextFoldBase.Next;
begin
inherited Next;
if (copy(FLineText, FTokenPos, FTokenEnd - FTokenPos) = '--') then
inc(FCurRange);
if (copy(FLineText, FTokenPos, FTokenEnd - FTokenPos) = '++') and (FCurRange > 0) then
dec(FCurRange);
end;
function TSynDemoHlContextFoldBase.GetTokenAttribute: TSynHighlighterAttributes;
begin
Result := inherited GetTokenAttribute;
if (Result = SpecialAttri) and (FCurRange > 0) then
Result := IdentifierAttribute;
end;
end.

View File

@ -0,0 +1,243 @@
unit SimpleHl;
(*
This is an example how to implement your own highlighter.
This example does allow to specify different colors for
- text (defaults to not-highlighted)
- spaces (defaults to silver frame)
- words, separated by spaces, that start with a,e,i,o,u (defaults to bold)
- the word "not" (defaults to red background)
See comments below and http://wiki.lazarus.freepascal.org/SynEdit_Highlighter
How it works:
- Creation
The Highlighter creates Attributes that it can return the Words and Spaces.
- SetLine
Is called by SynEdit before a line gets painted (or before highlight info is needed)
This is also called, each time the text changes fol *all* changed lines
and may even be called for all lines after the change up to the end of text.
After SetLine was called "GetToken*" should return information about the
first token on the line.
Note: Spaces are token too.
- Next
Scan to the next token, on the line that was set by "SetLine"
"GetToken*" should return info about that next token.
- GetEOL
Returns True, if "Next" was called while on the last token of the line.
- GetTokenEx, GetTokenAttribute
Provide info about the token found by "Next"
- Next, GetEOL. GetToken*
Are used by SynEdit to iterate over the Line.
Important: The tokens returned for each line, must represent the original
line-text (mothing added, nothing left out), and be returned in the correct order.
They are called very often and should perform ath high speed.
- GetToken, GetTokenPos, GetTokenKind
SynEdit uses them e.g for finding matching brackets. If GetTokenKind returns different values per Attribute, then brackets only match, if they are of the same kind (e.g, if there was a string attribute, brackets outside a string would not match brackets inside a string)
*)
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Graphics, SynEditTypes, SynEditHighlighter;
type
{ TSynDemoHl }
TSynDemoHl = class(TSynCustomHighlighter)
private
FNotAttri: TSynHighlighterAttributes;
fSpecialAttri: TSynHighlighterAttributes;
fIdentifierAttri: TSynHighlighterAttributes;
fSpaceAttri: TSynHighlighterAttributes;
procedure SetIdentifierAttri(AValue: TSynHighlighterAttributes);
procedure SetNotAttri(AValue: TSynHighlighterAttributes);
procedure SetSpaceAttri(AValue: TSynHighlighterAttributes);
procedure SetSpecialAttri(AValue: TSynHighlighterAttributes);
protected
// accesible for the other examples
FTokenPos, FTokenEnd: Integer;
FLineText: String;
public
procedure SetLine(const NewValue: String; LineNumber: Integer); override;
procedure Next; override;
function GetEol: Boolean; override;
procedure GetTokenEx(out TokenStart: PChar; out TokenLength: integer); override;
function GetTokenAttribute: TSynHighlighterAttributes; override;
public
function GetToken: String; override;
function GetTokenPos: Integer; override;
function GetTokenKind: integer; override;
function GetDefaultAttribute(Index: integer): TSynHighlighterAttributes; override;
constructor Create(AOwner: TComponent); override;
published
(* Define 4 Attributes, for the different highlights. *)
property SpecialAttri: TSynHighlighterAttributes read fSpecialAttri
write SetSpecialAttri;
property NotAttri: TSynHighlighterAttributes read FNotAttri
write SetNotAttri;
property IdentifierAttri: TSynHighlighterAttributes read fIdentifierAttri
write SetIdentifierAttri;
property SpaceAttri: TSynHighlighterAttributes read fSpaceAttri
write SetSpaceAttri;
end;
implementation
constructor TSynDemoHl.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
(* Create and initialize the attributes *)
fSpecialAttri := TSynHighlighterAttributes.Create('special', 'special');
AddAttribute(fSpecialAttri);
fSpecialAttri.Style := [fsBold];
FNotAttri := TSynHighlighterAttributes.Create('not', 'not');
AddAttribute(FNotAttri);
FNotAttri.Background := clRed;
fIdentifierAttri := TSynHighlighterAttributes.Create('ident', 'ident');
AddAttribute(fIdentifierAttri);
fSpaceAttri := TSynHighlighterAttributes.Create('space', 'space');
AddAttribute(fSpaceAttri);
fSpaceAttri.FrameColor := clSilver;
fSpaceAttri.FrameEdges := sfeAround;
end;
(* Setters for attributes / This allows using in Object inspector*)
procedure TSynDemoHl.SetIdentifierAttri(AValue: TSynHighlighterAttributes);
begin
fIdentifierAttri.Assign(AValue);
end;
procedure TSynDemoHl.SetNotAttri(AValue: TSynHighlighterAttributes);
begin
FNotAttri.Assign(AValue);
end;
procedure TSynDemoHl.SetSpaceAttri(AValue: TSynHighlighterAttributes);
begin
fSpaceAttri.Assign(AValue);
end;
procedure TSynDemoHl.SetSpecialAttri(AValue: TSynHighlighterAttributes);
begin
fSpecialAttri.Assign(AValue);
end;
procedure TSynDemoHl.SetLine(const NewValue: String; LineNumber: Integer);
begin
inherited;
FLineText := NewValue;
// Next will start at "FTokenEnd", so set this to 1
FTokenEnd := 1;
Next;
end;
procedure TSynDemoHl.Next;
var
l: Integer;
begin
// FTokenEnd should be at the start of the next Token (which is the Token we want)
FTokenPos := FTokenEnd;
// assume empty, will only happen for EOL
FTokenEnd := FTokenPos;
// Scan forward
// FTokenEnd will be set 1 after the last char. That is:
// - The first char of the next token
// - or past the end of line (which allows GetEOL to work)
l := length(FLineText);
If FTokenPos > l then
// At line end
exit
else
if FLineText[FTokenEnd] in [#9, ' '] then
// At Space? Find end of spaces
while (FTokenEnd <= l) and (FLineText[FTokenEnd] in [#0..#32]) do inc (FTokenEnd)
else
// At None-Space? Find end of None-spaces
while (FTokenEnd <= l) and not(FLineText[FTokenEnd] in [#9, ' ']) do inc (FTokenEnd)
end;
function TSynDemoHl.GetEol: Boolean;
begin
Result := FTokenPos > length(FLineText);
end;
procedure TSynDemoHl.GetTokenEx(out TokenStart: PChar; out TokenLength: integer);
begin
TokenStart := @FLineText[FTokenPos];
TokenLength := FTokenEnd - FTokenPos;
end;
function TSynDemoHl.GetTokenAttribute: TSynHighlighterAttributes;
begin
// Match the text, specified by FTokenPos and FTokenEnd
if FLineText[FTokenPos] in [#9, ' '] then
Result := SpaceAttri
else
if LowerCase(FLineText[FTokenPos]) in ['a', 'e', 'i', 'o', 'u'] then
Result := SpecialAttri
else
if LowerCase(copy(FLineText, FTokenPos, FTokenEnd - FTokenPos)) = 'not' then
Result := NotAttri
else
Result := IdentifierAttri;
end;
function TSynDemoHl.GetToken: String;
begin
Result := copy(FLineText, FTokenPos, FTokenEnd - FTokenPos);
end;
function TSynDemoHl.GetTokenPos: Integer;
begin
Result := FTokenPos - 1;
end;
function TSynDemoHl.GetDefaultAttribute(Index: integer): TSynHighlighterAttributes;
begin
// Some default attributes
case Index of
SYN_ATTR_COMMENT: Result := fSpecialAttri;
SYN_ATTR_IDENTIFIER: Result := fIdentifierAttri;
SYN_ATTR_WHITESPACE: Result := fSpaceAttri;
else Result := nil;
end;
end;
function TSynDemoHl.GetTokenKind: integer;
var
a: TSynHighlighterAttributes;
begin
// Map Attribute into a unique number
a := GetTokenAttribute;
Result := 0;
if a = fSpaceAttri then Result := 1;
if a = fSpecialAttri then Result := 2;
if a = fIdentifierAttri then Result := 3;
if a = FNotAttri then Result := 4;
end;
end.

View File

@ -0,0 +1,560 @@
object Form1: TForm1
Left = 365
Height = 443
Top = 142
Width = 655
Caption = 'Form1'
ClientHeight = 443
ClientWidth = 655
OnCreate = FormCreate
LCLVersion = '0.9.31'
inline SynEdit1: TSynEdit
Left = 0
Height = 383
Top = 0
Width = 655
Align = alTop
Anchors = [akTop, akLeft, akRight, akBottom]
Font.Height = -13
Font.Name = 'Courier New'
Font.Pitch = fpFixed
Font.Quality = fqNonAntialiased
ParentColor = False
ParentFont = False
TabOrder = 0
Gutter.Width = 57
Gutter.MouseActions = <>
RightGutter.Width = 0
RightGutter.MouseActions = <>
Keystrokes = <
item
Command = ecUp
ShortCut = 38
end
item
Command = ecSelUp
ShortCut = 8230
end
item
Command = ecScrollUp
ShortCut = 16422
end
item
Command = ecDown
ShortCut = 40
end
item
Command = ecSelDown
ShortCut = 8232
end
item
Command = ecScrollDown
ShortCut = 16424
end
item
Command = ecLeft
ShortCut = 37
end
item
Command = ecSelLeft
ShortCut = 8229
end
item
Command = ecWordLeft
ShortCut = 16421
end
item
Command = ecSelWordLeft
ShortCut = 24613
end
item
Command = ecRight
ShortCut = 39
end
item
Command = ecSelRight
ShortCut = 8231
end
item
Command = ecWordRight
ShortCut = 16423
end
item
Command = ecSelWordRight
ShortCut = 24615
end
item
Command = ecPageDown
ShortCut = 34
end
item
Command = ecSelPageDown
ShortCut = 8226
end
item
Command = ecPageBottom
ShortCut = 16418
end
item
Command = ecSelPageBottom
ShortCut = 24610
end
item
Command = ecPageUp
ShortCut = 33
end
item
Command = ecSelPageUp
ShortCut = 8225
end
item
Command = ecPageTop
ShortCut = 16417
end
item
Command = ecSelPageTop
ShortCut = 24609
end
item
Command = ecLineStart
ShortCut = 36
end
item
Command = ecSelLineStart
ShortCut = 8228
end
item
Command = ecEditorTop
ShortCut = 16420
end
item
Command = ecSelEditorTop
ShortCut = 24612
end
item
Command = ecLineEnd
ShortCut = 35
end
item
Command = ecSelLineEnd
ShortCut = 8227
end
item
Command = ecEditorBottom
ShortCut = 16419
end
item
Command = ecSelEditorBottom
ShortCut = 24611
end
item
Command = ecToggleMode
ShortCut = 45
end
item
Command = ecCopy
ShortCut = 16429
end
item
Command = ecPaste
ShortCut = 8237
end
item
Command = ecDeleteChar
ShortCut = 46
end
item
Command = ecCut
ShortCut = 8238
end
item
Command = ecDeleteLastChar
ShortCut = 8
end
item
Command = ecDeleteLastChar
ShortCut = 8200
end
item
Command = ecDeleteLastWord
ShortCut = 16392
end
item
Command = ecUndo
ShortCut = 32776
end
item
Command = ecRedo
ShortCut = 40968
end
item
Command = ecLineBreak
ShortCut = 13
end
item
Command = ecSelectAll
ShortCut = 16449
end
item
Command = ecCopy
ShortCut = 16451
end
item
Command = ecBlockIndent
ShortCut = 24649
end
item
Command = ecLineBreak
ShortCut = 16461
end
item
Command = ecInsertLine
ShortCut = 16462
end
item
Command = ecDeleteWord
ShortCut = 16468
end
item
Command = ecBlockUnindent
ShortCut = 24661
end
item
Command = ecPaste
ShortCut = 16470
end
item
Command = ecCut
ShortCut = 16472
end
item
Command = ecDeleteLine
ShortCut = 16473
end
item
Command = ecDeleteEOL
ShortCut = 24665
end
item
Command = ecUndo
ShortCut = 16474
end
item
Command = ecRedo
ShortCut = 24666
end
item
Command = ecGotoMarker0
ShortCut = 16432
end
item
Command = ecGotoMarker1
ShortCut = 16433
end
item
Command = ecGotoMarker2
ShortCut = 16434
end
item
Command = ecGotoMarker3
ShortCut = 16435
end
item
Command = ecGotoMarker4
ShortCut = 16436
end
item
Command = ecGotoMarker5
ShortCut = 16437
end
item
Command = ecGotoMarker6
ShortCut = 16438
end
item
Command = ecGotoMarker7
ShortCut = 16439
end
item
Command = ecGotoMarker8
ShortCut = 16440
end
item
Command = ecGotoMarker9
ShortCut = 16441
end
item
Command = ecSetMarker0
ShortCut = 24624
end
item
Command = ecSetMarker1
ShortCut = 24625
end
item
Command = ecSetMarker2
ShortCut = 24626
end
item
Command = ecSetMarker3
ShortCut = 24627
end
item
Command = ecSetMarker4
ShortCut = 24628
end
item
Command = ecSetMarker5
ShortCut = 24629
end
item
Command = ecSetMarker6
ShortCut = 24630
end
item
Command = ecSetMarker7
ShortCut = 24631
end
item
Command = ecSetMarker8
ShortCut = 24632
end
item
Command = ecSetMarker9
ShortCut = 24633
end
item
Command = EcFoldLevel1
ShortCut = 41009
end
item
Command = EcFoldLevel2
ShortCut = 41010
end
item
Command = EcFoldLevel1
ShortCut = 41011
end
item
Command = EcFoldLevel1
ShortCut = 41012
end
item
Command = EcFoldLevel1
ShortCut = 41013
end
item
Command = EcFoldLevel6
ShortCut = 41014
end
item
Command = EcFoldLevel7
ShortCut = 41015
end
item
Command = EcFoldLevel8
ShortCut = 41016
end
item
Command = EcFoldLevel9
ShortCut = 41017
end
item
Command = EcFoldLevel0
ShortCut = 41008
end
item
Command = EcFoldCurrent
ShortCut = 41005
end
item
Command = EcUnFoldCurrent
ShortCut = 41003
end
item
Command = EcToggleMarkupWord
ShortCut = 32845
end
item
Command = ecNormalSelect
ShortCut = 24654
end
item
Command = ecColumnSelect
ShortCut = 24643
end
item
Command = ecLineSelect
ShortCut = 24652
end
item
Command = ecTab
ShortCut = 9
end
item
Command = ecShiftTab
ShortCut = 8201
end
item
Command = ecMatchBracket
ShortCut = 24642
end
item
Command = ecColSelUp
ShortCut = 40998
end
item
Command = ecColSelDown
ShortCut = 41000
end
item
Command = ecColSelLeft
ShortCut = 40997
end
item
Command = ecColSelRight
ShortCut = 40999
end
item
Command = ecColSelPageDown
ShortCut = 40994
end
item
Command = ecColSelPageBottom
ShortCut = 57378
end
item
Command = ecColSelPageUp
ShortCut = 40993
end
item
Command = ecColSelPageTop
ShortCut = 57377
end
item
Command = ecColSelLineStart
ShortCut = 40996
end
item
Command = ecColSelLineEnd
ShortCut = 40995
end
item
Command = ecColSelEditorTop
ShortCut = 57380
end
item
Command = ecColSelEditorBottom
ShortCut = 57379
end>
MouseActions = <>
MouseSelActions = <>
Lines.Strings = (
'This is an example how to write a highlighter from scratch.'
'See the units for each example highlighter.'
'--'
'This is NOT about extending the IDE. This is about SynEdit and it''s Highlighter only.'
'Therefore this does not include: ++'
'- registration in the component pallette.'
'- Using the Object Inspector'
'Those steps are the same as they would be for any other self wriiten componont.'
''
'-(-'
'Lorem ipsum dolor sit amet, '
'consectetur adipisicing elit, '
'sed -- do eiusmod tempor incididunt ut labore et dolore magna aliqua. '
'-- (Nested double -) Ut enim ad minim veniam, '
'quis nostrud exercitation ++ (Nested double +) ullamco laboris nisi ut aliquip ex ea commodo consequat. '
'Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. '
'++ Excepteur sint occaecat cupidatat non proident, '
'sunt in culpa qui officia deserunt mollit anim id est laborum.'
'-(- --'
'Lorem ipsum dolor sit amet, '
'consectetur adipisicing elit, '
'sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. '
'++ Ut enim ad minim veniam, '
'quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. '
'Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. '
'Excepteur sint occaecat cupidatat non proident, '
'sunt in culpa qui officia deserunt mollit anim id est laborum.'
'-)-'
'-)-'
''
)
VisibleSpecialChars = [vscSpace, vscTabAtLast]
BracketHighlightStyle = sbhsBoth
BracketMatchColor.Background = clNone
BracketMatchColor.Foreground = clNone
BracketMatchColor.Style = [fsBold]
FoldedCodeColor.Background = clNone
FoldedCodeColor.Foreground = clGray
FoldedCodeColor.FrameColor = clGray
MouseLinkColor.Background = clNone
MouseLinkColor.Foreground = clBlue
LineHighlightColor.Background = clNone
LineHighlightColor.Foreground = clNone
inline SynLeftGutterPartList1: TSynGutterPartList
object SynGutterMarks1: TSynGutterMarks
Width = 24
MouseActions = <>
end
object SynGutterLineNumber1: TSynGutterLineNumber
Width = 17
MouseActions = <>
MarkupInfo.Background = clBtnFace
MarkupInfo.Foreground = clNone
DigitCount = 2
ShowOnlyLineNumbersMultiplesOf = 1
ZeroStart = False
LeadingZeros = False
end
object SynGutterChanges1: TSynGutterChanges
Width = 4
MouseActions = <>
ModifiedColor = 59900
SavedColor = clGreen
end
object SynGutterSeparator1: TSynGutterSeparator
Width = 2
MouseActions = <>
end
object SynGutterCodeFolding1: TSynGutterCodeFolding
MouseActions = <>
MarkupInfo.Background = clNone
MarkupInfo.Foreground = clGray
MouseActionsExpanded = <>
MouseActionsCollapsed = <>
end
end
end
object Button1: TButton
Left = 21
Height = 25
Top = 408
Width = 75
Anchors = [akLeft, akBottom]
Caption = 'SimpleHl'
OnClick = Button1Click
TabOrder = 1
end
object Button2: TButton
Left = 136
Height = 25
Top = 408
Width = 75
Anchors = [akLeft, akBottom]
Caption = 'ContextHl'
OnClick = Button2Click
TabOrder = 2
end
object Button3: TButton
Left = 256
Height = 25
Top = 408
Width = 75
Anchors = [akLeft, akBottom]
Caption = 'FoldHl'
OnClick = Button3Click
TabOrder = 3
end
end

View File

@ -0,0 +1,78 @@
unit Unit1;
(*
This is an example how to write a highlighter from scratch.
See the units for each example highlighter.
This is NOT about extending the IDE. This is about SynEdit and it's Highlighter only.
Therefore this does not include:
- registration in the component pallette.
- Using the Object Inspector
Those steps are the same as they would be for any other self wriiten componont.
*)
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, SynEdit, Forms, Controls, Graphics, Dialogs, StdCtrls,
SimpleHl, ContextHL, FoldHl;
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
SynEdit1: TSynEdit;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ private declarations }
FSynDemoHl: TSynDemoHl;
FSynDemoHlContext: TSynDemoHlContext;
FSynDemoHlFold: TSynDemoHlFold;
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
begin
FSynDemoHl := TSynDemoHl.Create(Self);
FSynDemoHlContext := TSynDemoHlContext.Create(Self);
FSynDemoHlFold := TSynDemoHlFold.Create(Self);
SynEdit1.Highlighter := FSynDemoHl;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
SynEdit1.Highlighter := FSynDemoHl;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
SynEdit1.Highlighter := FSynDemoHlContext;
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
SynEdit1.Highlighter := FSynDemoHlFold;
end;
end.