SynEdit: Added fold config for for XML/LFM

git-svn-id: trunk@22623 -
This commit is contained in:
martin 2009-11-16 13:42:30 +00:00
parent e92e4ee0d6
commit f7794cff2a
7 changed files with 314 additions and 48 deletions

View File

@ -43,6 +43,22 @@ uses
type type
{ TSynCustomFoldConfig }
TSynCustomFoldConfig = class(TPersistent)
private
FEnabled: Boolean;
FOnChange: TNotifyEvent;
procedure SetFEnabled(const AValue: Boolean);
protected
procedure DoOnChange;
public
procedure Assign(Src: TSynCustomFoldConfig); reintroduce; virtual;
property OnChange: TNotifyEvent read FOnChange write FOnChange;
published
property Enabled: Boolean read FEnabled write SetFEnabled;
end;
{ TSynCustomCodeFoldBlock } { TSynCustomCodeFoldBlock }
TSynCustomCodeFoldBlock = class TSynCustomCodeFoldBlock = class
@ -127,9 +143,10 @@ type
fRanges: TSynCustomHighlighterRanges; fRanges: TSynCustomHighlighterRanges;
FRootCodeFoldBlock: TSynCustomCodeFoldBlock; FRootCodeFoldBlock: TSynCustomCodeFoldBlock;
protected protected
function GetFoldConfig(Index: Integer): Boolean; virtual; function GetFoldConfig(Index: Integer): TSynCustomFoldConfig; virtual;
function GetFoldConfigCount: Integer; virtual; function GetFoldConfigCount: Integer; virtual;
procedure SetFoldConfig(Index: Integer; const AValue: Boolean); virtual; procedure SetFoldConfig(Index: Integer; const AValue: TSynCustomFoldConfig); virtual;
procedure DoFoldConfigChanged(Sender: TObject); virtual;
function GetFoldNodeInfo(Line, Index: Integer; Filter: TSynFoldActions): TSynFoldNodeInfo; virtual; function GetFoldNodeInfo(Line, Index: Integer; Filter: TSynFoldActions): TSynFoldNodeInfo; virtual;
function GetFoldNodeInfoCount(Line: Integer; Filter: TSynFoldActions): Integer; virtual; function GetFoldNodeInfoCount(Line: Integer; Filter: TSynFoldActions): Integer; virtual;
@ -174,7 +191,7 @@ type
LineNumber:Integer // 0 based LineNumber:Integer // 0 based
); override; ); override;
public public
property FoldConfig[Index: Integer]: Boolean property FoldConfig[Index: Integer]: TSynCustomFoldConfig
read GetFoldConfig write SetFoldConfig; read GetFoldConfig write SetFoldConfig;
property FoldConfigCount: Integer read GetFoldConfigCount; property FoldConfigCount: Integer read GetFoldConfigCount;
@ -347,9 +364,9 @@ begin
Result := 0; Result := 0;
end; end;
function TSynCustomFoldHighlighter.GetFoldConfig(Index: Integer): Boolean; function TSynCustomFoldHighlighter.GetFoldConfig(Index: Integer): TSynCustomFoldConfig;
begin begin
Result := False; Result := nil;
end; end;
function TSynCustomFoldHighlighter.GetFoldConfigCount: Integer; function TSynCustomFoldHighlighter.GetFoldConfigCount: Integer;
@ -357,10 +374,16 @@ begin
Result := 0; Result := 0;
end; end;
procedure TSynCustomFoldHighlighter.SetFoldConfig(Index: Integer; const AValue: Boolean); procedure TSynCustomFoldHighlighter.SetFoldConfig(Index: Integer; const AValue: TSynCustomFoldConfig);
begin begin
end; end;
procedure TSynCustomFoldHighlighter.DoFoldConfigChanged(Sender: TObject);
begin
FAttributeChangeNeedScan := True;
DefHighlightChange(self);
end;
function TSynCustomFoldHighlighter.GetFoldNodeInfo(Line, Index: Integer; function TSynCustomFoldHighlighter.GetFoldNodeInfo(Line, Index: Integer;
Filter: TSynFoldActions): TSynFoldNodeInfo; Filter: TSynFoldActions): TSynFoldNodeInfo;
begin begin
@ -750,5 +773,25 @@ begin
if FAllocatedCount=0 then Free; if FAllocatedCount=0 then Free;
end; end;
{ TSynCustomFoldConfig }
procedure TSynCustomFoldConfig.SetFEnabled(const AValue: Boolean);
begin
if FEnabled = AValue then exit;
FEnabled := AValue;
DoOnChange;
end;
procedure TSynCustomFoldConfig.DoOnChange;
begin
if assigned(FOnChange) then
FOnChange(self);
end;
procedure TSynCustomFoldConfig.Assign(Src: TSynCustomFoldConfig);
begin
Enabled := Src.Enabled;
end;
end. end.

View File

@ -77,6 +77,10 @@ type
TProcTableProc = procedure of object; TProcTableProc = procedure of object;
const
CountLfmCodeFoldBlockOffset: Pointer =
Pointer(PtrInt(Integer(high(TLfmCodeFoldBlockType))+1));
type type
{ TSynLFMSyn } { TSynLFMSyn }
@ -97,6 +101,7 @@ type
fSpaceAttri: TSynHighlighterAttributes; fSpaceAttri: TSynHighlighterAttributes;
fStringAttri: TSynHighlighterAttributes; fStringAttri: TSynHighlighterAttributes;
fSymbolAttri: TSynHighlighterAttributes; fSymbolAttri: TSynHighlighterAttributes;
FFoldConfig: Array [TLfmCodeFoldBlockType] of TSynCustomFoldConfig;
procedure AltProc; procedure AltProc;
procedure AsciiCharProc; procedure AsciiCharProc;
procedure BraceCloseProc; procedure BraceCloseProc;
@ -115,6 +120,8 @@ type
procedure SymbolProc; procedure SymbolProc;
procedure UnknownProc; procedure UnknownProc;
procedure MakeMethodTables; procedure MakeMethodTables;
procedure InitFoldConfig;
procedure DestroyFoldConfig;
protected protected
function GetIdentChars: TSynIdentChars; override; function GetIdentChars: TSynIdentChars; override;
function GetSampleSource: string; override; function GetSampleSource: string; override;
@ -126,11 +133,16 @@ type
(ABlockType: TLfmCodeFoldBlockType): TSynCustomCodeFoldBlock; (ABlockType: TLfmCodeFoldBlockType): TSynCustomCodeFoldBlock;
procedure EndLfmCodeFoldBlock; procedure EndLfmCodeFoldBlock;
function TopLfmCodeFoldBlockType(DownIndex: Integer = 0): TLfmCodeFoldBlockType; function TopLfmCodeFoldBlockType(DownIndex: Integer = 0): TLfmCodeFoldBlockType;
protected
function GetFoldConfig(Index: Integer): TSynCustomFoldConfig; override;
function GetFoldConfigCount: Integer; override;
procedure SetFoldConfig(Index: Integer; const AValue: TSynCustomFoldConfig); override;
public public
{$IFNDEF SYN_CPPB_1} class {$ENDIF} //mh 2000-07-14 {$IFNDEF SYN_CPPB_1} class {$ENDIF} //mh 2000-07-14
function GetLanguageName: string; override; function GetLanguageName: string; override;
public public
constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function GetDefaultAttribute(Index: integer): TSynHighlighterAttributes; function GetDefaultAttribute(Index: integer): TSynHighlighterAttributes;
override; override;
function GetEol: Boolean; override; function GetEol: Boolean; override;
@ -278,9 +290,29 @@ begin
end; end;
end; end;
procedure TSynLFMSyn.InitFoldConfig;
var
i: TLfmCodeFoldBlockType;
begin
for i := low(TLfmCodeFoldBlockType) to high(TLfmCodeFoldBlockType) do begin
FFoldConfig[i] := TSynCustomFoldConfig.Create;
FFoldConfig[i].OnChange := @DoFoldConfigChanged;
FFoldConfig[i].Enabled := True;
end;
end;
procedure TSynLFMSyn.DestroyFoldConfig;
var
i: TLfmCodeFoldBlockType;
begin
for i := low(TLfmCodeFoldBlockType) to high(TLfmCodeFoldBlockType) do
FFoldConfig[i].Free;
end;
constructor TSynLFMSyn.Create(AOwner: TComponent); constructor TSynLFMSyn.Create(AOwner: TComponent);
begin begin
inherited Create(AOwner); inherited Create(AOwner);
InitFoldConfig;
fCommentAttri := TSynHighlighterAttributes.Create(SYNS_AttrComment, SYNS_XML_AttrComment); fCommentAttri := TSynHighlighterAttributes.Create(SYNS_AttrComment, SYNS_XML_AttrComment);
fCommentAttri.Style := [fsItalic]; fCommentAttri.Style := [fsItalic];
AddAttribute(fCommentAttri); AddAttribute(fCommentAttri);
@ -303,6 +335,12 @@ begin
fRange := rsUnknown; fRange := rsUnknown;
end; end;
destructor TSynLFMSyn.Destroy;
begin
DestroyFoldConfig;
inherited Destroy;
end;
procedure TSynLFMSyn.SetLine({$IFDEF FPC}const {$ENDIF}NewValue: String; procedure TSynLFMSyn.SetLine({$IFDEF FPC}const {$ENDIF}NewValue: String;
LineNumber: Integer); LineNumber: Integer);
begin begin
@ -698,13 +736,23 @@ begin
end; end;
function TSynLFMSyn.StartLfmCodeFoldBlock(ABlockType: TLfmCodeFoldBlockType): TSynCustomCodeFoldBlock; function TSynLFMSyn.StartLfmCodeFoldBlock(ABlockType: TLfmCodeFoldBlockType): TSynCustomCodeFoldBlock;
var
FoldBlock: Boolean;
p: PtrInt;
begin begin
Result := StartCodeFoldBlock(Pointer(PtrInt(ABlockType))); FoldBlock := FFoldConfig[ABlockType].Enabled;
p := 0;
if not FoldBlock then
p := PtrInt(CountLfmCodeFoldBlockOffset);
Result := StartCodeFoldBlock(p + Pointer(PtrInt(ABlockType)), FoldBlock);
end; end;
procedure TSynLFMSyn.EndLfmCodeFoldBlock; procedure TSynLFMSyn.EndLfmCodeFoldBlock;
var
DecreaseLevel: Boolean;
begin begin
EndCodeFoldBlock(); DecreaseLevel := TopCodeFoldBlockType < CountLfmCodeFoldBlockOffset;
EndCodeFoldBlock(DecreaseLevel);
end; end;
function TSynLFMSyn.TopLfmCodeFoldBlockType(DownIndex: Integer): TLfmCodeFoldBlockType; function TSynLFMSyn.TopLfmCodeFoldBlockType(DownIndex: Integer): TLfmCodeFoldBlockType;
@ -712,6 +760,26 @@ begin
Result := TLfmCodeFoldBlockType(PtrUInt(TopCodeFoldBlockType(DownIndex))); Result := TLfmCodeFoldBlockType(PtrUInt(TopCodeFoldBlockType(DownIndex)));
end; end;
function TSynLFMSyn.GetFoldConfig(Index: Integer): TSynCustomFoldConfig;
begin
// + 1 as we skip cfbtNone;
Result := FFoldConfig[TLfmCodeFoldBlockType(Index + 1)];
end;
function TSynLFMSyn.GetFoldConfigCount: Integer;
begin
// excluded cfbtNone;
Result := ord(high(TLfmCodeFoldBlockType)) - ord(low(TLfmCodeFoldBlockType));
end;
procedure TSynLFMSyn.SetFoldConfig(Index: Integer; const AValue: TSynCustomFoldConfig);
begin
BeginUpdate;
FFoldConfig[TLfmCodeFoldBlockType(Index + 1)].Assign(AValue);
EndUpdate;
// Todo: Since all synedits will rescan => delete all foldranges
end;
{$IFNDEF SYN_CPPB_1} //mh 2000-07-14 {$IFNDEF SYN_CPPB_1} //mh 2000-07-14
initialization initialization
RegisterPlaceableHighlighter(TSynLFMSyn); RegisterPlaceableHighlighter(TSynLFMSyn);

View File

@ -269,7 +269,7 @@ type
FNodeInfoLine, FNodeInfoCount: Integer; FNodeInfoLine, FNodeInfoCount: Integer;
FNodeInfoList: Array of TSynFoldNodeInfo; FNodeInfoList: Array of TSynFoldNodeInfo;
FDividerDrawConfig: Array [TSynPasDividerDrawLocation] of TSynDividerDrawConfig; FDividerDrawConfig: Array [TSynPasDividerDrawLocation] of TSynDividerDrawConfig;
FFoldConfig: Array [TPascalCodeFoldBlockType] of Boolean; FFoldConfig: Array [TPascalCodeFoldBlockType] of TSynCustomFoldConfig;
procedure GrowNodeInfoList; procedure GrowNodeInfoList;
function GetPasCodeFoldRange: TSynPasSynRange; function GetPasCodeFoldRange: TSynPasSynRange;
procedure SetCompilerMode(const AValue: TPascalCompilerMode); procedure SetCompilerMode(const AValue: TPascalCompilerMode);
@ -405,6 +405,7 @@ type
procedure CreateDividerDrawConfig; procedure CreateDividerDrawConfig;
procedure DestroyDividerDrawConfig; procedure DestroyDividerDrawConfig;
procedure InitFoldConfig; procedure InitFoldConfig;
procedure DestroyFoldConfig;
protected protected
function GetIdentChars: TSynIdentChars; override; function GetIdentChars: TSynIdentChars; override;
function IsFilterStored: boolean; override; //mh 2000-10-08 function IsFilterStored: boolean; override; //mh 2000-10-08
@ -439,9 +440,9 @@ type
function GetDividerDrawConfig(Index: Integer): TSynDividerDrawConfig; override; function GetDividerDrawConfig(Index: Integer): TSynDividerDrawConfig; override;
function GetDividerDrawConfigCount: Integer; override; function GetDividerDrawConfigCount: Integer; override;
function GetFoldConfig(Index: Integer): Boolean; override; function GetFoldConfig(Index: Integer): TSynCustomFoldConfig; override;
function GetFoldConfigCount: Integer; override; function GetFoldConfigCount: Integer; override;
procedure SetFoldConfig(Index: Integer; const AValue: Boolean); override; procedure SetFoldConfig(Index: Integer; const AValue: TSynCustomFoldConfig); override;
public public
{$IFNDEF SYN_CPPB_1} class {$ENDIF} {$IFNDEF SYN_CPPB_1} class {$ENDIF}
function GetCapabilities: TSynHighlighterCapabilities; override; function GetCapabilities: TSynHighlighterCapabilities; override;
@ -1986,6 +1987,7 @@ end; { Create }
destructor TSynPasSyn.Destroy; destructor TSynPasSyn.Destroy;
begin begin
DestroyDividerDrawConfig; DestroyDividerDrawConfig;
DestroyFoldConfig;
inherited Destroy; inherited Destroy;
end; end;
@ -2986,7 +2988,7 @@ end;
procedure TSynPasSyn.StartCustomCodeFoldBlock(ABlockType: TPascalCodeFoldBlockType); procedure TSynPasSyn.StartCustomCodeFoldBlock(ABlockType: TPascalCodeFoldBlockType);
begin begin
if not FFoldConfig[ABlockType] then exit; if not FFoldConfig[ABlockType].Enabled then exit;
if FCatchNodeInfo then begin // exclude subblocks, because they do not increase the foldlevel yet if FCatchNodeInfo then begin // exclude subblocks, because they do not increase the foldlevel yet
GrowNodeInfoList; GrowNodeInfoList;
InitNode(FNodeInfoList[FNodeInfoCount], +1, ABlockType, [sfaOpen, sfaFold]); InitNode(FNodeInfoList[FNodeInfoCount], +1, ABlockType, [sfaOpen, sfaFold]);
@ -3002,7 +3004,7 @@ end;
procedure TSynPasSyn.EndCustomCodeFoldBlock(ABlockType: TPascalCodeFoldBlockType); procedure TSynPasSyn.EndCustomCodeFoldBlock(ABlockType: TPascalCodeFoldBlockType);
begin begin
if not FFoldConfig[ABlockType] then exit; if not FFoldConfig[ABlockType].Enabled then exit;
if FCatchNodeInfo then begin // exclude subblocks, because they do not increase the foldlevel yet if FCatchNodeInfo then begin // exclude subblocks, because they do not increase the foldlevel yet
GrowNodeInfoList; GrowNodeInfoList;
InitNode(FNodeInfoList[FNodeInfoCount], -1, ABlockType, [sfaClose, sfaFold]); InitNode(FNodeInfoList[FNodeInfoCount], -1, ABlockType, [sfaClose, sfaFold]);
@ -3034,7 +3036,7 @@ var
FoldBlock: Boolean; FoldBlock: Boolean;
act: TSynFoldActions; act: TSynFoldActions;
begin begin
FoldBlock := FFoldConfig[ABlockType]; FoldBlock := FFoldConfig[ABlockType].Enabled;
p := 0; p := 0;
if FCatchNodeInfo then begin // exclude subblocks, because they do not increase the foldlevel yet if FCatchNodeInfo then begin // exclude subblocks, because they do not increase the foldlevel yet
GrowNodeInfoList; GrowNodeInfoList;
@ -3290,11 +3292,22 @@ procedure TSynPasSyn.InitFoldConfig;
var var
i: TPascalCodeFoldBlockType; i: TPascalCodeFoldBlockType;
begin begin
for i := low(TPascalCodeFoldBlockType) to high(TPascalCodeFoldBlockType) do for i := low(TPascalCodeFoldBlockType) to high(TPascalCodeFoldBlockType) do begin
FFoldConfig[i] := i in [cfbtBeginEnd, cfbtTopBeginEnd, cfbtNestedComment, FFoldConfig[i] := TSynCustomFoldConfig.Create;
FFoldConfig[i].OnChange := @DoFoldConfigChanged;
FFoldConfig[i].Enabled := i in [cfbtBeginEnd, cfbtTopBeginEnd, cfbtNestedComment,
cfbtProcedure, cfbtUses, cfbtLocalVarType, cfbtClass, cfbtProcedure, cfbtUses, cfbtLocalVarType, cfbtClass,
cfbtClassSection, cfbtRecord, cfbtRepeat, cfbtCase, cfbtClassSection, cfbtRecord, cfbtRepeat, cfbtCase,
cfbtAsm, cfbtRegion]; cfbtAsm, cfbtRegion];
end;
end;
procedure TSynPasSyn.DestroyFoldConfig;
var
i: TPascalCodeFoldBlockType;
begin
for i := low(TPascalCodeFoldBlockType) to high(TPascalCodeFoldBlockType) do
FFoldConfig[i].Free;
end; end;
function TSynPasSyn.CreateRangeList: TSynHighlighterRangeList; function TSynPasSyn.CreateRangeList: TSynHighlighterRangeList;
@ -3316,7 +3329,7 @@ begin
TSynHighlighterPasRangeList(CurrentRanges).PasRangeInfo[Index] := FSynPasRangeInfo; TSynHighlighterPasRangeList(CurrentRanges).PasRangeInfo[Index] := FSynPasRangeInfo;
end; end;
function TSynPasSyn.GetFoldConfig(Index: Integer): Boolean; function TSynPasSyn.GetFoldConfig(Index: Integer): TSynCustomFoldConfig;
begin begin
// + 1 as we skip cfbtNone; // + 1 as we skip cfbtNone;
Result := FFoldConfig[TPascalCodeFoldBlockType(Index + 1)]; Result := FFoldConfig[TPascalCodeFoldBlockType(Index + 1)];
@ -3329,13 +3342,11 @@ begin
ord(low(TPascalCodeFoldBlockType)); ord(low(TPascalCodeFoldBlockType));
end; end;
procedure TSynPasSyn.SetFoldConfig(Index: Integer; const AValue: Boolean); procedure TSynPasSyn.SetFoldConfig(Index: Integer; const AValue: TSynCustomFoldConfig);
begin begin
if FFoldConfig[TPascalCodeFoldBlockType(Index + 1)] = AValue then BeginUpdate;
exit; FFoldConfig[TPascalCodeFoldBlockType(Index + 1)].Assign(AValue);
FFoldConfig[TPascalCodeFoldBlockType(Index + 1)] := AValue; EndUpdate;
FAttributeChangeNeedScan := True;
DefHighlightChange(self);
// Todo: Since all synedits will rescan => delete all foldranges // Todo: Since all synedits will rescan => delete all foldranges
end; end;

View File

@ -98,13 +98,19 @@ type
TXmlCodeFoldBlockType = ( TXmlCodeFoldBlockType = (
cfbtXmlNone, cfbtXmlNone,
cfbtXmlElement, // <foo> cfbtXmlNode, // <foo>...</node>
cfbtXmlComment, // <!-- --> cfbtXmlComment, // <!-- -->
cfbtXmlCData, // <![CDATA[ ]]> cfbtXmlCData, // <![CDATA[ ]]>
cfbtXmlDocType, // <!DOCTYPE cfbtXmlDocType, // <!DOCTYPE
cfbtXmlProcess // <? cfbtXmlProcess // <?
); );
const
CountXmlCodeFoldBlockOffset: Pointer =
Pointer(PtrInt(Integer(high(TXmlCodeFoldBlockType))+1));
type
TSynXmlRangeInfo = record TSynXmlRangeInfo = record
ElementOpenList: Array of String; // List of words opened in this line (and still open at the end of line) ElementOpenList: Array of String; // List of words opened in this line (and still open at the end of line)
ElementCloseList: Array of Smallint; // include close, for open on same line ElementCloseList: Array of Smallint; // include close, for open on same line
@ -156,6 +162,7 @@ type
fSymbolAttri: TSynHighlighterAttributes; fSymbolAttri: TSynHighlighterAttributes;
fProcTable: array[#0..#255] of TProcTableProc; fProcTable: array[#0..#255] of TProcTableProc;
FWantBracesParsed: Boolean; FWantBracesParsed: Boolean;
FFoldConfig: Array [TXmlCodeFoldBlockType] of TSynCustomFoldConfig;
procedure NullProc; procedure NullProc;
procedure CarriageReturnProc; procedure CarriageReturnProc;
procedure LineFeedProc; procedure LineFeedProc;
@ -178,6 +185,8 @@ type
procedure EntityRefProc; procedure EntityRefProc;
procedure QEntityRefProc; procedure QEntityRefProc;
procedure AEntityRefProc; procedure AEntityRefProc;
procedure InitFoldConfig;
procedure DestroyFoldConfig;
protected protected
function UpdateRangeInfoAtLine(Index: Integer): Boolean; override; // Returns true if range changed function UpdateRangeInfoAtLine(Index: Integer): Boolean; override; // Returns true if range changed
function GetIdentChars: TSynIdentChars; override; function GetIdentChars: TSynIdentChars; override;
@ -188,16 +197,21 @@ type
function CreateRangeList: TSynHighlighterRangeList; override; function CreateRangeList: TSynHighlighterRangeList; override;
function StartXmlCodeFoldBlock(ABlockType: TXmlCodeFoldBlockType): TSynCustomCodeFoldBlock; function StartXmlCodeFoldBlock(ABlockType: TXmlCodeFoldBlockType): TSynCustomCodeFoldBlock;
function StartXmlElemCodeFoldBlock(ABlockType: TXmlCodeFoldBlockType; function StartXmlNodeCodeFoldBlock(ABlockType: TXmlCodeFoldBlockType;
OpenPos: Integer; AName: String): TSynCustomCodeFoldBlock; OpenPos: Integer; AName: String): TSynCustomCodeFoldBlock;
procedure EndXmlCodeFoldBlock; procedure EndXmlCodeFoldBlock;
procedure EndXmlElemCodeFoldBlock(ClosePos: Integer = -1; AName: String = ''); procedure EndXmlNodeCodeFoldBlock(ClosePos: Integer = -1; AName: String = '');
function TopXmlCodeFoldBlockType(DownIndex: Integer = 0): TXmlCodeFoldBlockType; function TopXmlCodeFoldBlockType(DownIndex: Integer = 0): TXmlCodeFoldBlockType;
protected
function GetFoldConfig(Index: Integer): TSynCustomFoldConfig; override;
function GetFoldConfigCount: Integer; override;
procedure SetFoldConfig(Index: Integer; const AValue: TSynCustomFoldConfig); override;
public public
{$IFNDEF SYN_CPPB_1} class {$ENDIF} {$IFNDEF SYN_CPPB_1} class {$ENDIF}
function GetLanguageName: string; override; function GetLanguageName: string; override;
public public
constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function GetDefaultAttribute(Index: integer): TSynHighlighterAttributes; function GetDefaultAttribute(Index: integer): TSynHighlighterAttributes;
override; override;
function GetEol: Boolean; override; function GetEol: Boolean; override;
@ -267,6 +281,7 @@ const
constructor TSynXMLSyn.Create(AOwner: TComponent); constructor TSynXMLSyn.Create(AOwner: TComponent);
begin begin
inherited Create(AOwner); inherited Create(AOwner);
InitFoldConfig;
fElementAttri:= TSynHighlighterAttributes.Create(SYNS_AttrElementName, SYNS_XML_AttrElementName); fElementAttri:= TSynHighlighterAttributes.Create(SYNS_AttrElementName, SYNS_XML_AttrElementName);
fTextAttri:= TSynHighlighterAttributes.Create(SYNS_AttrText, SYNS_XML_AttrText); fTextAttri:= TSynHighlighterAttributes.Create(SYNS_AttrText, SYNS_XML_AttrText);
@ -340,6 +355,12 @@ begin
fDefaultFilter := SYNS_FilterXML; fDefaultFilter := SYNS_FilterXML;
end; end;
destructor TSynXMLSyn.Destroy;
begin
DestroyFoldConfig;
inherited Destroy;
end;
procedure TSynXMLSyn.MakeMethodTables; procedure TSynXMLSyn.MakeMethodTables;
var var
i: Char; i: Char;
@ -465,8 +486,8 @@ end;
procedure TSynXMLSyn.GreaterThanProc; procedure TSynXMLSyn.GreaterThanProc;
begin begin
if (Run > 0) and (fLine[Run - 1] = '/') then if (Run > 0) and (fLine[Run - 1] = '/') then
if TopXmlCodeFoldBlockType = cfbtXmlElement then if TopXmlCodeFoldBlockType = cfbtXmlNode then
EndXmlElemCodeFoldBlock; EndXmlNodeCodeFoldBlock;
fTokenId := tkSymbol; fTokenId := tkSymbol;
fRange:= rsText; fRange:= rsText;
@ -618,10 +639,10 @@ begin
while (fLine[Run] in NameChars) do Inc(Run); while (fLine[Run] in NameChars) do Inc(Run);
if fRange = rsOpenElement then if fRange = rsOpenElement then
StartXmlElemCodeFoldBlock(cfbtXmlElement, NameStart, Copy(fLine, NameStart + 1, Run - NameStart)); StartXmlNodeCodeFoldBlock(cfbtXmlNode, NameStart, Copy(fLine, NameStart + 1, Run - NameStart));
if fRange = rsCloseElement then if fRange = rsCloseElement then
EndXmlElemCodeFoldBlock(NameStart, Copy(fLine, NameStart + 1, Run - NameStart)); // TODO: defer until ">" reached EndXmlNodeCodeFoldBlock(NameStart, Copy(fLine, NameStart + 1, Run - NameStart)); // TODO: defer until ">" reached
fRange := rsAttribute; fRange := rsAttribute;
fTokenID := tkElement; fTokenID := tkElement;
@ -791,6 +812,25 @@ begin
fRange := rsAPosAttrValue; fRange := rsAPosAttrValue;
end; end;
procedure TSynXMLSyn.InitFoldConfig;
var
i: TXmlCodeFoldBlockType;
begin
for i := low(TXmlCodeFoldBlockType) to high(TXmlCodeFoldBlockType) do begin
FFoldConfig[i] := TSynCustomFoldConfig.Create;
FFoldConfig[i].OnChange := @DoFoldConfigChanged;
FFoldConfig[i].Enabled := True;
end;
end;
procedure TSynXMLSyn.DestroyFoldConfig;
var
i: TXmlCodeFoldBlockType;
begin
for i := low(TXmlCodeFoldBlockType) to high(TXmlCodeFoldBlockType) do
FFoldConfig[i].Free;
end;
function TSynXMLSyn.UpdateRangeInfoAtLine(Index: Integer): Boolean; function TSynXMLSyn.UpdateRangeInfoAtLine(Index: Integer): Boolean;
var var
InfoOpenLenChanged, InfoCloseLenChanged: Boolean; InfoOpenLenChanged, InfoCloseLenChanged: Boolean;
@ -1084,16 +1124,23 @@ begin
end; end;
function TSynXMLSyn.StartXmlCodeFoldBlock(ABlockType: TXmlCodeFoldBlockType): TSynCustomCodeFoldBlock; function TSynXMLSyn.StartXmlCodeFoldBlock(ABlockType: TXmlCodeFoldBlockType): TSynCustomCodeFoldBlock;
var
FoldBlock: Boolean;
p: PtrInt;
begin begin
if CodeFoldRange.CodeFoldStackSize >= MaxFoldNestDeep then exit; FoldBlock := FFoldConfig[ABlockType].Enabled;
StartCodeFoldBlock(Pointer(PtrInt(ABlockType))); p := 0;
if not FoldBlock then
p := PtrInt(CountXmlCodeFoldBlockOffset);
Result := StartCodeFoldBlock(p + Pointer(PtrInt(ABlockType)), FoldBlock);
end; end;
function TSynXMLSyn.StartXmlElemCodeFoldBlock(ABlockType: TXmlCodeFoldBlockType; function TSynXMLSyn.StartXmlNodeCodeFoldBlock(ABlockType: TXmlCodeFoldBlockType;
OpenPos: Integer; AName: String): TSynCustomCodeFoldBlock; OpenPos: Integer; AName: String): TSynCustomCodeFoldBlock;
var var
i: Integer; i: Integer;
begin begin
if not FFoldConfig[cfbtXmlNode].Enabled then exit;
If IsScanning then begin If IsScanning then begin
AName := LowerCase(AName); AName := LowerCase(AName);
i := Length(FXmlRangeInfo.ElementOpenList); i := Length(FXmlRangeInfo.ElementOpenList);
@ -1108,20 +1155,23 @@ begin
end; end;
end; end;
inc(FXmlRangeInfoOpenPos); inc(FXmlRangeInfoOpenPos);
StartXmlCodeFoldBlock(ABlockType); result := StartXmlCodeFoldBlock(ABlockType);
end; end;
procedure TSynXMLSyn.EndXmlCodeFoldBlock; procedure TSynXMLSyn.EndXmlCodeFoldBlock;
var
DecreaseLevel: Boolean;
begin begin
EndCodeFoldBlock(); DecreaseLevel := TopCodeFoldBlockType < CountXmlCodeFoldBlockOffset;
EndCodeFoldBlock(DecreaseLevel);
end; end;
procedure TSynXMLSyn.EndXmlElemCodeFoldBlock(ClosePos: Integer = -1; AName: String = ''); procedure TSynXMLSyn.EndXmlNodeCodeFoldBlock(ClosePos: Integer = -1; AName: String = '');
var var
cnt, i, k, lvl: Integer; cnt, i, k, lvl: Integer;
LInfo: Array of String; LInfo: Array of String;
begin begin
if not (TopXmlCodeFoldBlockType = cfbtXmlElement) then debugln('---- XXXXX TSynXMLSyn.EndXmlElemCodeFoldBlock XXXXX'); if not FFoldConfig[cfbtXmlNode].Enabled then exit;
AName := LowerCase(AName); AName := LowerCase(AName);
cnt := 0; cnt := 0;
@ -1133,7 +1183,6 @@ begin
cnt := 1; cnt := 1;
i := FXmlRangeInfoOpenPos; i := FXmlRangeInfoOpenPos;
while i > 0 do begin while i > 0 do begin
if TopXmlCodeFoldBlockType(FXmlRangeInfoOpenPos - i) <> cfbtXmlElement then debugln('---- XXXXX TSynXMLSyn.EndXmlElemCodeFoldBlock XXXXX');
if (FXmlRangeInfo.ElementOpenList[i-1] = AName) then if (FXmlRangeInfo.ElementOpenList[i-1] = AName) then
break; break;
dec(i); dec(i);
@ -1194,6 +1243,26 @@ begin
Result := TXmlCodeFoldBlockType(PtrUInt(TopCodeFoldBlockType(DownIndex))); Result := TXmlCodeFoldBlockType(PtrUInt(TopCodeFoldBlockType(DownIndex)));
end; end;
function TSynXMLSyn.GetFoldConfig(Index: Integer): TSynCustomFoldConfig;
begin
// + 1 as we skip cfbtNone;
Result := FFoldConfig[TXmlCodeFoldBlockType(Index + 1)];
end;
function TSynXMLSyn.GetFoldConfigCount: Integer;
begin
// excluded cfbtNone;
Result := ord(high(TXmlCodeFoldBlockType)) - ord(low(TXmlCodeFoldBlockType));
end;
procedure TSynXMLSyn.SetFoldConfig(Index: Integer; const AValue: TSynCustomFoldConfig);
begin
BeginUpdate;
FFoldConfig[TXmlCodeFoldBlockType(Index + 1)].Assign(AValue);
EndUpdate;
// Todo: Since all synedits will rescan => delete all foldranges
end;
{ TSynHighlighterXmlRangeList } { TSynHighlighterXmlRangeList }
function TSynHighlighterXmlRangeList.GetXmlRangeInfo(Index: Integer): TSynXmlRangeInfo; function TSynHighlighterXmlRangeList.GetXmlRangeInfo(Index: Integer): TSynXmlRangeInfo;

View File

@ -617,14 +617,62 @@ const
Index: ord(cfbtRegion)-1; Enabled: True) Index: ord(cfbtRegion)-1; Enabled: True)
); );
EditorOptionsFoldInfoLFM: Array [0..2] of TEditorOptionsFoldInfo
= (
( Name: dlgFoldLfmObject;
Xml: 'Object';
Index: ord(cfbtLfmObject)-1;
Enabled: True
),
( Name: dlgFoldLfmList;
Xml: 'List';
Index: ord(cfbtLfmList)-1;
Enabled: True
),
( Name: dlgFoldLfmItem;
Xml: 'Item';
Index: ord(cfbtLfmItem)-1;
Enabled: True
)
);
EditorOptionsFoldInfoXML: Array [0..4] of TEditorOptionsFoldInfo
= (
( Name: dlgFoldXmlNode;
Xml: 'Node';
Index: ord(cfbtXmlNode)-1;
Enabled: True
),
( Name: dlgFoldXmlComment;
Xml: 'Comment';
Index: ord(cfbtXmlComment)-1;
Enabled: True
),
( Name: dlgFoldXmlCData;
Xml: 'CData';
Index: ord(cfbtXmlCData)-1;
Enabled: True
),
( Name: dlgFoldXmlDocType;
Xml: 'DocType';
Index: ord(cfbtXmlDocType)-1;
Enabled: True
),
( Name: dlgFoldXmlProcess;
Xml: 'ProcessInstr';
Index: ord(cfbtXmlProcess)-1;
Enabled: True
)
);
EditorOptionsFoldDefaults: array[TLazSyntaxHighlighter] of EditorOptionsFoldDefaults: array[TLazSyntaxHighlighter] of
TEditorOptionsFoldRecord = TEditorOptionsFoldRecord =
( (Count: 0; Info: nil), // none ( (Count: 0; Info: nil), // none
(Count: 0; Info: nil), // text (Count: 0; Info: nil), // text
(Count: 20; Info: {$IFDEF FPC}@{$ENDIF}EditorOptionsFoldInfoPas[0]), // Freepas (Count: 20; Info: {$IFDEF FPC}@{$ENDIF}EditorOptionsFoldInfoPas[0]), // Freepas
(Count: 20; Info: {$IFDEF FPC}@{$ENDIF}EditorOptionsFoldInfoPas[0]), // pas (Count: 20; Info: {$IFDEF FPC}@{$ENDIF}EditorOptionsFoldInfoPas[0]), // pas
(Count: 0; Info: nil), // lfm (Count: 3; Info: {$IFDEF FPC}@{$ENDIF}EditorOptionsFoldInfoLFM[0]), // lfm
(Count: 0; Info: nil), // xml (Count: 5; Info: {$IFDEF FPC}@{$ENDIF}EditorOptionsFoldInfoXML[0]), // xml
(Count: 0; Info: nil), // html (Count: 0; Info: nil), // html
(Count: 0; Info: nil), // cpp (Count: 0; Info: nil), // cpp
(Count: 0; Info: nil), // perl (Count: 0; Info: nil), // perl
@ -2411,6 +2459,16 @@ begin
EditorOptionsFoldInfoPas[18].Name := dlgFoldPasIfDef; EditorOptionsFoldInfoPas[18].Name := dlgFoldPasIfDef;
EditorOptionsFoldInfoPas[19].Name := dlgFoldPasUserRegion; EditorOptionsFoldInfoPas[19].Name := dlgFoldPasUserRegion;
EditorOptionsFoldInfoLFM[ 0].Name := dlgFoldLfmObject;
EditorOptionsFoldInfoLFM[ 1].Name := dlgFoldLfmList;
EditorOptionsFoldInfoLFM[ 2].Name := dlgFoldLfmItem;
EditorOptionsFoldInfoXML[ 0].Name := dlgFoldXmlNode;
EditorOptionsFoldInfoXML[ 1].Name := dlgFoldXmlComment;
EditorOptionsFoldInfoXML[ 2].Name := dlgFoldXmlCData;
EditorOptionsFoldInfoXML[ 3].Name := dlgFoldXmlDocType;
EditorOptionsFoldInfoXML[ 4].Name := dlgFoldXmlProcess;
EditorOptionsDividerInfoPas[0].Name:=dlgDivPasUnitSectionName; EditorOptionsDividerInfoPas[0].Name:=dlgDivPasUnitSectionName;
EditorOptionsDividerInfoPas[1].Name:=dlgDivPasUsesName; EditorOptionsDividerInfoPas[1].Name:=dlgDivPasUsesName;
EditorOptionsDividerInfoPas[2].Name:=dlgDivPasVarGlobalName; EditorOptionsDividerInfoPas[2].Name:=dlgDivPasVarGlobalName;
@ -3428,8 +3486,12 @@ begin
ConfName := TheFoldInfo.Info^[i].Xml; ConfName := TheFoldInfo.Info^[i].Xml;
Path := 'EditorOptions/FoldConfig/Lang' + Path := 'EditorOptions/FoldConfig/Lang' +
StrToValidXMLName(Syn.LanguageName) + '/Type' + ConfName + '/' ; StrToValidXMLName(Syn.LanguageName) + '/Type' + ConfName + '/' ;
TSynCustomFoldHighlighter(Syn).FoldConfig[TheFoldInfo.Info^[i].Index] := // try reading the old config first
TSynCustomFoldHighlighter(Syn).FoldConfig[TheFoldInfo.Info^[i].Index].Enabled :=
XMLConfig.GetValue(Path + 'Enabled/Value', XMLConfig.GetValue(Path + 'Enabled/Value',
TSynCustomFoldHighlighter(Syn).FoldConfig[TheFoldInfo.Info^[i].Index].Enabled);
XMLConfig.ReadObject(Path + 'Settings/',
TSynCustomFoldHighlighter(Syn).FoldConfig[TheFoldInfo.Info^[i].Index],
TSynCustomFoldHighlighter(Syn).FoldConfig[TheFoldInfo.Info^[i].Index]); TSynCustomFoldHighlighter(Syn).FoldConfig[TheFoldInfo.Info^[i].Index]);
end; end;
end; end;
@ -3446,10 +3508,10 @@ begin
if h < 0 then exit; if h < 0 then exit;
if (syn is TSynCustomFoldHighlighter) then begin if (syn is TSynCustomFoldHighlighter) then begin
TheFoldInfo := EditorOptionsFoldDefaults[HighlighterList[h].TheType]; TheFoldInfo := EditorOptionsFoldDefaults[HighlighterList[h].TheType];
for i := 0 to TheFoldInfo.Count - 1 do begin for i := 0 to TheFoldInfo.Count - 1 do
TSynCustomFoldHighlighter(Syn).FoldConfig[TheFoldInfo.Info^[i].Index] with TSynCustomFoldHighlighter(Syn).FoldConfig[TheFoldInfo.Info^[i].Index] do begin
:= TheFoldInfo.Info^[i].Enabled; Enabled := TheFoldInfo.Info^[i].Enabled;
end; end;
end; end;
end; end;
@ -3476,7 +3538,8 @@ begin
ConfName := TheFoldInfo.Info^[i].Xml; ConfName := TheFoldInfo.Info^[i].Xml;
Path := 'EditorOptions/FoldConfig/Lang' + Path := 'EditorOptions/FoldConfig/Lang' +
StrToValidXMLName(Syn.LanguageName) + '/Type' + ConfName + '/' ; StrToValidXMLName(Syn.LanguageName) + '/Type' + ConfName + '/' ;
XMLConfig.SetDeleteValue(Path + 'Enabled/Value', XMLConfig.DeletePath(Path + 'Enabled/');
XMLConfig.WriteObject(Path + 'Settings/',
TSynCustomFoldHighlighter(Syn).FoldConfig[TheFoldInfo.Info^[i].Index], TSynCustomFoldHighlighter(Syn).FoldConfig[TheFoldInfo.Info^[i].Index],
TSynCustomFoldHighlighter(DefSyn).FoldConfig[TheFoldInfo.Info^[i].Index]); TSynCustomFoldHighlighter(DefSyn).FoldConfig[TheFoldInfo.Info^[i].Index]);
end; end;

View File

@ -99,7 +99,7 @@ begin
for i := 0 to FCurFoldInfo.Count - 1 do begin for i := 0 to FCurFoldInfo.Count - 1 do begin
FoldConfigCheckListBox.Items.add(FCurFoldInfo.Info^[i].Name); FoldConfigCheckListBox.Items.add(FCurFoldInfo.Info^[i].Name);
FoldConfigCheckListBox.Checked[i] := FoldConfigCheckListBox.Checked[i] :=
TSynCustomFoldHighlighter(FCurHighlighter).FoldConfig[FCurFoldInfo.Info^[i].Index]; TSynCustomFoldHighlighter(FCurHighlighter).FoldConfig[FCurFoldInfo.Info^[i].Index].Enabled;
end; end;
end; end;
@ -110,7 +110,7 @@ begin
if not (assigned(FCurHighlighter) and if not (assigned(FCurHighlighter) and
(FCurHighlighter is TSynCustomFoldHighlighter)) then exit; (FCurHighlighter is TSynCustomFoldHighlighter)) then exit;
for i := 0 to FCurFoldInfo.Count - 1 do for i := 0 to FCurFoldInfo.Count - 1 do
TSynCustomFoldHighlighter(FCurHighlighter).FoldConfig[FCurFoldInfo.Info^[i].Index] TSynCustomFoldHighlighter(FCurHighlighter).FoldConfig[FCurFoldInfo.Info^[i].Index].Enabled
:= FoldConfigCheckListBox.Checked[i]; := FoldConfigCheckListBox.Checked[i];
end; end;
@ -130,7 +130,9 @@ begin
SynClass := LazSyntaxHighlighterClasses[SynType]; SynClass := LazSyntaxHighlighterClasses[SynType];
Result := SynClass.Create(nil); Result := SynClass.Create(nil);
FHighlighters[SynType] := Result; FHighlighters[SynType] := Result;
Result.BeginUpdate;
EditorOpts.ReadHighlighterFoldSettings(Result); EditorOpts.ReadHighlighterFoldSettings(Result);
result.EndUpdate;
end; end;
procedure TEditorCodefoldingOptionsFrame.ClearHighlighters; procedure TEditorCodefoldingOptionsFrame.ClearHighlighters;

View File

@ -1389,6 +1389,16 @@ resourcestring
dlgFoldPasIfDef = '{$IfDef}'; dlgFoldPasIfDef = '{$IfDef}';
dlgFoldPasUserRegion = '{%Region}'; dlgFoldPasUserRegion = '{%Region}';
dlgFoldLfmObject = 'Object (inherited, inline)';
dlgFoldLfmList = 'List <>';
dlgFoldLfmItem = 'Item';
dlgFoldXmlNode = 'Node';
dlgFoldXmlComment = 'Comment';
dlgFoldXmlCData = 'CData';
dlgFoldXmlDocType = 'DocType';
dlgFoldXmlProcess = 'Processing Instruction';
dlgMouseFoldExpFoldOne = 'Fold One (All Expanded)'; dlgMouseFoldExpFoldOne = 'Fold One (All Expanded)';
dlgMouseFoldExpFoldAll = 'Fold All (All Expanded)'; dlgMouseFoldExpFoldAll = 'Fold All (All Expanded)';
dlgMouseFoldColFoldOne = 'Fold One (Some Colapsed)'; dlgMouseFoldColFoldOne = 'Fold One (Some Colapsed)';