From b69ccc3438bcbd4663a6ec33de88873ff5e73241 Mon Sep 17 00:00:00 2001 From: martin Date: Wed, 14 Apr 2010 02:09:43 +0000 Subject: [PATCH] SynEdit: Folding for html git-svn-id: trunk@24616 - --- .gitattributes | 1 + .../synedit/synedithighlighterfoldbase.pas | 55 ++- .../synedit/synedithighlighterxmlbase.pas | 361 ++++++++++++++++++ components/synedit/synhighlighterhtml.pp | 113 +++++- components/synedit/synhighlighterlfm.pas | 54 +-- components/synedit/synhighlighterpas.pp | 62 +-- components/synedit/synhighlighterxml.pas | 292 ++------------ 7 files changed, 568 insertions(+), 370 deletions(-) create mode 100644 components/synedit/synedithighlighterxmlbase.pas diff --git a/.gitattributes b/.gitattributes index e744c0dcb7..9eba804bd1 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1983,6 +1983,7 @@ components/synedit/syneditexport.pas svneol=native#text/pascal components/synedit/syneditfoldedview.pp svneol=native#text/plain components/synedit/synedithighlighter.pp svneol=native#text/pascal components/synedit/synedithighlighterfoldbase.pas svneol=native#text/plain +components/synedit/synedithighlighterxmlbase.pas svneol=native#text/pascal components/synedit/syneditkeycmds.pp svneol=native#text/pascal components/synedit/syneditlazdsgn.lrs svneol=native#text/pascal components/synedit/syneditlazdsgn.pas svneol=native#text/pascal diff --git a/components/synedit/synedithighlighterfoldbase.pas b/components/synedit/synedithighlighterfoldbase.pas index afe0f2eb94..663335954c 100644 --- a/components/synedit/synedithighlighterfoldbase.pas +++ b/components/synedit/synedithighlighterfoldbase.pas @@ -138,16 +138,22 @@ type { TSynCustomFoldHighlighter } TSynCustomFoldHighlighter = class(TSynCustomHighlighter) + protected + // Config + FFoldConfig: Array of TSynCustomFoldConfig; + function GetFoldConfig(Index: Integer): TSynCustomFoldConfig; virtual; + procedure SetFoldConfig(Index: Integer; const AValue: TSynCustomFoldConfig); virtual; + function GetFoldConfigCount: Integer; virtual; + function GetFoldConfigInternalCount: Integer; virtual; + function GetFoldConfigInstance(Index: Integer): TSynCustomFoldConfig; virtual; + procedure InitFoldConfig; + procedure DestroyFoldConfig; + procedure DoFoldConfigChanged(Sender: TObject); virtual; private FCodeFoldRange: TSynCustomHighlighterRange; fRanges: TSynCustomHighlighterRanges; FRootCodeFoldBlock: TSynCustomCodeFoldBlock; protected - function GetFoldConfig(Index: Integer): TSynCustomFoldConfig; virtual; - function GetFoldConfigCount: Integer; virtual; - procedure SetFoldConfig(Index: Integer; const AValue: TSynCustomFoldConfig); virtual; - procedure DoFoldConfigChanged(Sender: TObject); virtual; - function GetFoldNodeInfo(Line, Index: Integer; Filter: TSynFoldActions): TSynFoldNodeInfo; virtual; function GetFoldNodeInfoCount(Line: Integer; Filter: TSynFoldActions): Integer; virtual; property CodeFoldRange: TSynCustomHighlighterRange read FCodeFoldRange; @@ -270,6 +276,8 @@ end; constructor TSynCustomFoldHighlighter.Create(AOwner: TComponent); begin + SetLength(FFoldConfig, GetFoldConfigInternalCount); + InitFoldConfig; fRanges:=AllocateHighlighterRanges(TSynCustomHighlighterClass(ClassType)); CreateRootCodeFoldBlock; inherited Create(AOwner); @@ -280,9 +288,11 @@ end; destructor TSynCustomFoldHighlighter.Destroy; begin inherited Destroy; + DestroyFoldConfig; FreeAndNil(FCodeFoldRange); FreeAndNil(FRootCodeFoldBlock); fRanges.Release; + FFoldConfig := nil; end; function TSynCustomFoldHighlighter.GetRange: pointer; @@ -366,7 +376,14 @@ end; function TSynCustomFoldHighlighter.GetFoldConfig(Index: Integer): TSynCustomFoldConfig; begin - Result := nil; + Result := FFoldConfig[Index]; +end; + +procedure TSynCustomFoldHighlighter.SetFoldConfig(Index: Integer; const AValue: TSynCustomFoldConfig); +begin + BeginUpdate; + FFoldConfig[Index].Assign(AValue); + EndUpdate; end; function TSynCustomFoldHighlighter.GetFoldConfigCount: Integer; @@ -374,8 +391,32 @@ begin Result := 0; end; -procedure TSynCustomFoldHighlighter.SetFoldConfig(Index: Integer; const AValue: TSynCustomFoldConfig); +function TSynCustomFoldHighlighter.GetFoldConfigInternalCount: Integer; begin + Result := 0; +end; + +function TSynCustomFoldHighlighter.GetFoldConfigInstance(Index: Integer): TSynCustomFoldConfig; +begin + Result := TSynCustomFoldConfig.Create; + Result.OnChange := @DoFoldConfigChanged; + Result.Enabled := False; +end; + +procedure TSynCustomFoldHighlighter.InitFoldConfig; +var + i: Integer; +begin + for i := 0 to high(FFoldConfig) do + FFoldConfig[i] := GetFoldConfigInstance(i); +end; + +procedure TSynCustomFoldHighlighter.DestroyFoldConfig; +var + i: Integer; +begin + for i := 0 to high(FFoldConfig) do + FFoldConfig[i].Free; end; procedure TSynCustomFoldHighlighter.DoFoldConfigChanged(Sender: TObject); diff --git a/components/synedit/synedithighlighterxmlbase.pas b/components/synedit/synedithighlighterxmlbase.pas new file mode 100644 index 0000000000..ad9dbae059 --- /dev/null +++ b/components/synedit/synedithighlighterxmlbase.pas @@ -0,0 +1,361 @@ +{------------------------------------------------------------------------------- +The contents of this file are subject to the Mozilla Public License +Version 1.1 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for +the specific language governing rights and limitations under the License. + +The Original Code is: SynHighlighterXML.pas, released 2000-11-20. +The Initial Author of this file is Jeff Rafter. +All Rights Reserved. + +Contributors to the SynEdit and mwEdit projects are listed in the +Contributors.txt file. + +Alternatively, the contents of this file may be used under the terms of the +GNU General Public License Version 2 or later (the "GPL"), in which case +the provisions of the GPL are applicable instead of those above. +If you wish to allow use of your version of this file only under the terms +of the GPL and not to allow others to use your version of this file +under the MPL, indicate your decision by deleting the provisions above and +replace them with the notice and other provisions required by the GPL. +If you do not delete the provisions above, a recipient may use your version +of this file under either the MPL or the GPL. +} + +(* Provides folding for Xml and Html *) +unit SynEditHighlighterXMLBase; + +interface + +{$I SynEdit.inc} + +uses + SysUtils, Classes, math, LCLType, + SynEditTypes, SynEditTextBuffer, SynEditHighlighter, SynEditHighlighterFoldBase; + +type + + TSynXmlRangeInfo = record + 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 + end; + + { TSynHighlighterXmlRangeList } + + TSynHighlighterXmlRangeList = class(TSynHighlighterRangeList) + private + function GetXmlRangeInfo(Index: Integer): TSynXmlRangeInfo; + procedure SetXmlRangeInfo(Index: Integer; const AValue: TSynXmlRangeInfo); + protected + procedure SetCapacity(const AValue: Integer); override; + function ItemSize: Integer; override; + public + procedure Move(AFrom, ATo, ALen: Integer); override; + property XmlRangeInfo[Index: Integer]: TSynXmlRangeInfo + read GetXmlRangeInfo write SetXmlRangeInfo; + end; + + + TSynCustomXmlHighlighter = class(TSynCustomFoldHighlighter) + private + FXmlRangeInfo: TSynXmlRangeInfo; + FXmlRangeInfoChanged: Boolean; + FXmlRangeInfoOpenPos: integer; + FXmlRangeInfoClosePos: integer; + protected + function CreateRangeList: TSynHighlighterRangeList; override; + function UpdateRangeInfoAtLine(Index: Integer): Boolean; override; // Returns true if range changed + + function StartXmlCodeFoldBlock(ABlockType: Integer): TSynCustomCodeFoldBlock; + function StartXmlNodeCodeFoldBlock(ABlockType: Integer; OpenPos: Integer; + AName: String): TSynCustomCodeFoldBlock; + procedure EndXmlCodeFoldBlock; + procedure EndXmlNodeCodeFoldBlock(ClosePos: Integer = -1; AName: String = ''); + public + procedure SetLine({$IFDEF FPC}const {$ENDIF}NewValue: string; LineNumber:Integer); override; + public + function FoldOpenCount(ALineIndex: Integer; AType: Integer = 0): integer; override; + function FoldCloseCount(ALineIndex: Integer; AType: Integer = 0): integer; override; + function FoldNestCount(ALineIndex: Integer; AType: Integer = 0): integer; override; + function FoldLineLength(ALineIndex, FoldIndex: Integer): integer; override; + // TODO: make private + function MinimumFoldLevel(ALineIndex: Integer): integer; override; + function EndFoldLevel(ALineIndex: Integer): integer; override; + end; + +implementation + +const + MaxFoldNestDeep = 500; + +function TSynCustomXmlHighlighter.CreateRangeList: TSynHighlighterRangeList; +begin + Result := TSynHighlighterXmlRangeList.Create; +end; + +function TSynCustomXmlHighlighter.UpdateRangeInfoAtLine(Index: Integer): Boolean; +var + InfoOpenLenChanged, InfoCloseLenChanged: Boolean; +begin + Result := inherited UpdateRangeInfoAtLine(Index); + InfoOpenLenChanged := Length(FXmlRangeInfo.ElementOpenList) <> FXmlRangeInfoOpenPos; + InfoCloseLenChanged := Length(FXmlRangeInfo.ElementCloseList) <> FXmlRangeInfoClosePos; + if FXmlRangeInfoChanged or InfoOpenLenChanged or InfoCloseLenChanged then begin + Result := True; + if InfoOpenLenChanged then + SetLength(FXmlRangeInfo.ElementOpenList, FXmlRangeInfoOpenPos); + if InfoCloseLenChanged then + SetLength(FXmlRangeInfo.ElementCloseList, FXmlRangeInfoClosePos); + TSynHighlighterXmlRangeList(CurrentRanges).XmlRangeInfo[LineIndex] := FXmlRangeInfo; // Store on this line + FXmlRangeInfoChanged := False; + end; +end; + +procedure TSynCustomXmlHighlighter.SetLine({$IFDEF FPC}const {$ENDIF}NewValue: string; + LineNumber:Integer); +begin + inherited; + FXmlRangeInfo := TSynHighlighterXmlRangeList(CurrentRanges).XmlRangeInfo[LineIndex]; // From this line, not from the previous line + FXmlRangeInfoChanged := False; + FXmlRangeInfoOpenPos := 0; + FXmlRangeInfoClosePos := 0; +end; + +function TSynCustomXmlHighlighter.FoldOpenCount(ALineIndex: Integer; AType: Integer): integer; +begin + If AType <> 0 then exit(0); + Result := EndFoldLevel(ALineIndex) - MinimumFoldLevel(ALineIndex); +end; + +function TSynCustomXmlHighlighter.FoldCloseCount(ALineIndex: Integer; AType: Integer): integer; +begin + If AType <> 0 then exit(0); + Result := EndFoldLevel(ALineIndex - 1) - MinimumFoldLevel(ALineIndex); +end; + +function TSynCustomXmlHighlighter.FoldNestCount(ALineIndex: Integer; AType: Integer): integer; +begin + If AType <> 0 then exit(0); + Result := EndFoldLevel(ALineIndex); +end; + +function TSynCustomXmlHighlighter.FoldLineLength(ALineIndex, FoldIndex: Integer): integer; +var + i, lvl, cnt: Integer; + e, m: Integer; +begin + //atype := FoldTypeAtNodeIndex(ALineIndex, FoldIndex); + cnt := CurrentLines.Count; + e := EndFoldLevel(ALineIndex); + m := MinimumFoldLevel(ALineIndex); + lvl := Min(m+1+FoldIndex, e); + i := ALineIndex + 1; + while (i < cnt) and (MinimumFoldLevel(i) >= lvl) do inc(i); + // check if fold last line of block (not mixed "end begin") + // and not lastlinefix + if (i = cnt) or (EndFoldLevel(i) > MinimumFoldLevel(i)) then + dec(i); + // Amount of lines, that will become invisible (excludes the cfCollapsed line) + Result := i - ALineIndex; +end; + +function TSynCustomXmlHighlighter.MinimumFoldLevel(ALineIndex: Integer): integer; +var + r: TSynCustomHighlighterRange; +begin + if (ALineIndex < 0) or (ALineIndex >= CurrentLines.Count) then + exit(0); + r := TSynCustomHighlighterRange(CurrentRanges[ALineIndex]); + if (r <> nil) and (Pointer(r) <> NullRange) then + Result := r.MinimumCodeFoldBlockLevel + else + Result := 0; +end; + +function TSynCustomXmlHighlighter.EndFoldLevel(ALineIndex: Integer): integer; +var + r: TSynCustomHighlighterRange; +begin + if (ALineIndex < 0) or (ALineIndex >= CurrentLines.Count) then + exit(0); + r := TSynCustomHighlighterRange(CurrentRanges[ALineIndex]); + if (r <> nil) and (Pointer(r) <> NullRange) then + Result := r.CodeFoldStackSize + else + Result := 0; +end; + +function TSynCustomXmlHighlighter.StartXmlCodeFoldBlock(ABlockType: Integer): TSynCustomCodeFoldBlock; +var + FoldBlock: Boolean; + p: PtrInt; +begin + FoldBlock := FFoldConfig[ABlockType].Enabled; + p := 0; + if not FoldBlock then + p := PtrInt(GetFoldConfigInternalCount); + Result := StartCodeFoldBlock(p + Pointer(PtrInt(ABlockType)), FoldBlock); +end; + +function TSynCustomXmlHighlighter.StartXmlNodeCodeFoldBlock(ABlockType: Integer; + OpenPos: Integer; AName: String): TSynCustomCodeFoldBlock; +var + i: Integer; +begin + If IsScanning then begin + AName := LowerCase(AName); + i := Length(FXmlRangeInfo.ElementOpenList); + if (FXmlRangeInfoOpenPos < i) then begin + if (FXmlRangeInfo.ElementOpenList[FXmlRangeInfoOpenPos] <> AName) then begin + FXmlRangeInfo.ElementOpenList[FXmlRangeInfoOpenPos] := AName; + FXmlRangeInfoChanged := true; // TODO:if this node closes on the same line, it may not be amodified .... + end; + end else begin // append - modified will be deteced by the new length + SetLength(FXmlRangeInfo.ElementOpenList, FXmlRangeInfoOpenPos + 10); + FXmlRangeInfo.ElementOpenList[FXmlRangeInfoOpenPos] := AName; + end; + end; + inc(FXmlRangeInfoOpenPos); + result := StartXmlCodeFoldBlock(ABlockType); +end; + +procedure TSynCustomXmlHighlighter.EndXmlCodeFoldBlock; +var + DecreaseLevel: Boolean; +begin + DecreaseLevel := TopCodeFoldBlockType < Pointer(PtrInt(GetFoldConfigInternalCount)); + EndCodeFoldBlock(DecreaseLevel); +end; + +procedure TSynCustomXmlHighlighter.EndXmlNodeCodeFoldBlock(ClosePos: Integer = -1; AName: String = ''); +var + cnt, i, k, lvl: Integer; + LInfo: Array of String; +begin + AName := LowerCase(AName); + + cnt := 0; + If IsScanning then begin + if (AName = '') and (CodeFoldRange.CodeFoldStackSize > 0) then begin + cnt := 1; + end + else begin + cnt := 1; + i := FXmlRangeInfoOpenPos; + while i > 0 do begin + if (FXmlRangeInfo.ElementOpenList[i-1] = AName) then + break; + dec(i); + inc(cnt); + end; + + if i = 0 then begin + i := LineIndex - 1; + lvl := EndFoldLevel(i); + while i >= 0 do begin + if MinimumFoldLevel(i) < lvl then begin + LInfo := TSynHighlighterXmlRangeList(CurrentRanges).XmlRangeInfo[i].ElementOpenList; + k := length(LInfo) - Max(EndFoldLevel(i) - lvl, 0) - 1; + while (k >= 0) do begin + if (LInfo[k] = AName) then + break; + inc(cnt); + dec(k); + dec(lvl); + end; + if k >= 0 then break; + end; + dec(i); + end; + + if (i < 0) or (cnt > CodeFoldRange.CodeFoldStackSize ) then cnt := 0; // never opened, do not close + end; + end; + + i := Length(FXmlRangeInfo.ElementCloseList); + if (FXmlRangeInfoClosePos < i) then begin + if (FXmlRangeInfo.ElementCloseList[FXmlRangeInfoClosePos] <> cnt) then begin + FXmlRangeInfo.ElementCloseList[FXmlRangeInfoClosePos] := cnt; + FXmlRangeInfoChanged := true; + end; + end else begin // append - modified will be deteced by the new length + SetLength(FXmlRangeInfo.ElementCloseList, FXmlRangeInfoClosePos + 10); + FXmlRangeInfo.ElementCloseList[FXmlRangeInfoClosePos] := cnt; + end; + end + else begin + if FXmlRangeInfoClosePos < length(FXmlRangeInfo.ElementCloseList) then + cnt := FXmlRangeInfo.ElementCloseList[FXmlRangeInfoClosePos] + else + cnt := 0; + end; + inc(FXmlRangeInfoClosePos); + + for i := 1 to cnt do begin + if FXmlRangeInfoOpenPos > 0 then + dec(FXmlRangeInfoOpenPos); + EndXmlCodeFoldBlock; + end; +end; + +{ TSynHighlighterXmlRangeList } + +function TSynHighlighterXmlRangeList.GetXmlRangeInfo(Index: Integer): TSynXmlRangeInfo; +begin + if (Index < 0) or (Index >= Count) then begin + Result.ElementOpenList := nil; + exit; + end; + Result := TSynXmlRangeInfo((ItemPointer[Index] + inherited ItemSize)^); +end; + +procedure TSynHighlighterXmlRangeList.SetXmlRangeInfo(Index: Integer; + const AValue: TSynXmlRangeInfo); +begin + TSynXmlRangeInfo((ItemPointer[Index] + inherited ItemSize)^) := AValue; +end; + +procedure TSynHighlighterXmlRangeList.SetCapacity(const AValue: Integer); +var + i: LongInt; +begin + for i := AValue to Capacity-1 do + with TSynXmlRangeInfo((ItemPointer[i] + inherited ItemSize)^) do begin + ElementOpenList := nil; + ElementCloseList := nil; + end; + inherited SetCapacity(AValue); +end; + +function TSynHighlighterXmlRangeList.ItemSize: Integer; +begin + Result := inherited ItemSize + SizeOf(TSynXmlRangeInfo); +end; + +procedure TSynHighlighterXmlRangeList.Move(AFrom, ATo, ALen: Integer); +var + i: LongInt; +begin + if ATo > AFrom then + for i:= Max(AFrom + ALen, ATo) to ATo + ALen - 1 do // move forward + with TSynXmlRangeInfo((ItemPointer[i] + inherited ItemSize)^) do begin + ElementOpenList := nil; + ElementCloseList := nil; + end + else + for i:= ATo to Min(ATo + ALen , AFrom) - 1 do // move backward + with TSynXmlRangeInfo((ItemPointer[i] + inherited ItemSize)^) do begin + ElementOpenList := nil; + ElementCloseList := nil; + end; + inherited Move(AFrom, ATo, ALen); +end; + +end. + + + diff --git a/components/synedit/synhighlighterhtml.pp b/components/synedit/synhighlighterhtml.pp index 7baa330502..aaeaf3ccd1 100644 --- a/components/synedit/synhighlighterhtml.pp +++ b/components/synedit/synhighlighterhtml.pp @@ -55,7 +55,8 @@ uses Windows, Messages, Registry, {$ENDIF} Classes, Controls, Graphics, - SynEditTypes, SynEditHighlighter; + SynEditTypes, SynEditHighlighter, SynEditHighlighterXMLBase, + SynEditHighlighterFoldBase; const MAX_ESCAPEAMPS = 151; @@ -223,10 +224,20 @@ type TRangeState = (rsAmpersand, rsASP, rsComment, rsKey, rsParam, rsText, rsUnKnown, rsValue); + THtmlCodeFoldBlockType = ( + cfbtHtmlNode, // ... + cfbtHtmlComment, // + cfbtHtmlAsp, // <% asp %> + // internal types / not configurable + cfbtHtmlNone + ); + TProcTableProc = procedure of object; TIdentFuncTableFunc = function: TtkTokenKind of object; - TSynHTMLSyn = class(TSynCustomHighlighter) + { TSynHTMLSyn } + + TSynHTMLSyn = class(TSynCustomXmlHighlighter) private fAndCode: Integer; fRange: TRangeState; @@ -407,6 +418,19 @@ type procedure AmpersandProc; protected function GetIdentChars: TSynIdentChars; override; + protected + // folding + procedure CreateRootCodeFoldBlock; override; + function GetFoldConfigInstance(Index: Integer): TSynCustomFoldConfig; override; + + function StartHtmlCodeFoldBlock(ABlockType: THtmlCodeFoldBlockType): TSynCustomCodeFoldBlock; + function StartHtmlNodeCodeFoldBlock(ABlockType: THtmlCodeFoldBlockType; + OpenPos: Integer; AName: String): TSynCustomCodeFoldBlock; + procedure EndHtmlNodeCodeFoldBlock(ClosePos: Integer = -1; AName: String = ''); + function TopHtmlCodeFoldBlockType(DownIndex: Integer = 0): THtmlCodeFoldBlockType; + + function GetFoldConfigCount: Integer; override; + function GetFoldConfigInternalCount: Integer; override; public {$IFNDEF SYN_CPPB_1} class {$ENDIF} //mh 2000-07-14 function GetLanguageName: string; override; @@ -1974,6 +1998,7 @@ end; procedure TSynHTMLSyn.SetLine(const NewValue: string; LineNumber:Integer); begin + inherited; fLine := PChar(NewValue); Run := 0; fLineNumber := LineNumber; @@ -1993,6 +2018,8 @@ begin then begin fRange := rsText; Inc(Run); + if TopHtmlCodeFoldBlockType = cfbtHtmlAsp then + EndHtmlNodeCodeFoldBlock; break; end; Inc(Run); @@ -2020,6 +2047,8 @@ begin then begin fRange := rsText; Inc(Run); + if TopHtmlCodeFoldBlockType = cfbtHtmlComment then + EndHtmlNodeCodeFoldBlock; break; end; Inc(Run); @@ -2029,20 +2058,22 @@ end; procedure TSynHTMLSyn.BraceOpenProc; begin Inc(Run); - if (fLine[Run] = '!') and (fLine[Run + 1] = '-') and (fLine[Run + 2] = '-') + if (Run <= length(fLine)-2) and (fLine[Run] = '!') and (fLine[Run + 1] = '-') and (fLine[Run + 2] = '-') then begin fRange := rsComment; fTokenID := tkComment; + StartHtmlCodeFoldBlock(cfbtHtmlComment); Inc(Run, 3); - end else begin - if fLine[Run]= '%' then begin - fRange := rsASP; - fTokenID := tkASP; - Inc(Run); - end else begin - fRange := rsKey; - fTokenID := tkSymbol; - end; + end + else if fLine[Run]= '%' then begin + fRange := rsASP; + fTokenID := tkASP; + StartHtmlCodeFoldBlock(cfbtHtmlAsp); + Inc(Run); + end + else begin + fRange := rsKey; + fTokenID := tkSymbol; end; end; @@ -2080,6 +2111,10 @@ begin begin fRange := rsParam; fTokenID := IdentKind((fLine + Run)); + if fLine[Run] = '/' then + EndHtmlNodeCodeFoldBlock(Run+1, copy(fline, Run+2, fStringLen-1)) + else if fLine[Run] <> '!' then + StartHtmlNodeCodeFoldBlock(cfbtHtmlNode, Run, copy(fline, Run+1, fStringLen)); Inc(Run, fStringLen); end; rsValue: @@ -2266,16 +2301,19 @@ end; function TSynHTMLSyn.GetRange: Pointer; begin - Result := Pointer(PtrInt(fRange)); + CodeFoldRange.RangeType:=Pointer(PtrUInt(Integer(fRange))); + Result := inherited; end; procedure TSynHTMLSyn.SetRange(Value: Pointer); begin - fRange := TRangeState(PtrUInt(Value)); + inherited; + fRange := TRangeState(Integer(PtrUInt(CodeFoldRange.RangeType))); end; procedure TSynHTMLSyn.ReSetRange; begin + inherited; fRange:= rsText; end; @@ -2284,6 +2322,53 @@ begin Result := ['0'..'9', 'a'..'z', 'A'..'Z']; end; +procedure TSynHTMLSyn.CreateRootCodeFoldBlock; +begin + inherited CreateRootCodeFoldBlock; + RootCodeFoldBlock.InitRootBlockType(Pointer(PtrInt(cfbtHtmlNone))); +end; + +function TSynHTMLSyn.GetFoldConfigInstance(Index: Integer): TSynCustomFoldConfig; +begin + Result := inherited GetFoldConfigInstance(Index); + Result.Enabled := True; +end; + +function TSynHTMLSyn.StartHtmlCodeFoldBlock(ABlockType: THtmlCodeFoldBlockType): TSynCustomCodeFoldBlock; +begin + Result := inherited StartXmlCodeFoldBlock(ord(ABlockType)); +end; + +function TSynHTMLSyn.StartHtmlNodeCodeFoldBlock(ABlockType: THtmlCodeFoldBlockType; + OpenPos: Integer; AName: String): TSynCustomCodeFoldBlock; +begin + if not FFoldConfig[ord(cfbtHtmlNode)].Enabled then exit; + Result := inherited StartXmlNodeCodeFoldBlock(ord(ABlockType), OpenPos, AName); +end; + +procedure TSynHTMLSyn.EndHtmlNodeCodeFoldBlock(ClosePos: Integer; AName: String); +begin + if not FFoldConfig[ord(cfbtHtmlNode)].Enabled then exit; + inherited EndXmlNodeCodeFoldBlock(ClosePos, AName); +end; + +function TSynHTMLSyn.TopHtmlCodeFoldBlockType(DownIndex: Integer): THtmlCodeFoldBlockType; +begin + Result := THtmlCodeFoldBlockType(PtrUInt(TopCodeFoldBlockType(DownIndex))); +end; + +function TSynHTMLSyn.GetFoldConfigCount: Integer; +begin + // excluded cfbtHtmlNone; + Result := ord(high(THtmlCodeFoldBlockType)) - ord(low(THtmlCodeFoldBlockType)); +end; + +function TSynHTMLSyn.GetFoldConfigInternalCount: Integer; +begin + // include cfbtHtmlNone; + Result := ord(high(THtmlCodeFoldBlockType)) - ord(low(THtmlCodeFoldBlockType)) + 1; +end; + {$IFNDEF SYN_CPPB_1} class {$ENDIF} //mh 2000-07-14 function TSynHTMLSyn.GetLanguageName: string; begin diff --git a/components/synedit/synhighlighterlfm.pas b/components/synedit/synhighlighterlfm.pas index 6e84257dcc..38ea7d0338 100644 --- a/components/synedit/synhighlighterlfm.pas +++ b/components/synedit/synhighlighterlfm.pas @@ -69,10 +69,11 @@ type TRangeState = (rsANil, rsComment, rsUnKnown); TLfmCodeFoldBlockType = ( - cfbtLfmNone, cfbtLfmObject, // object, inherited, inline cfbtLfmList, // <> - cfbtLfmItem // Item + cfbtLfmItem, // Item + // internal type / no config + cfbtLfmNone ); TProcTableProc = procedure of object; @@ -101,7 +102,6 @@ type fSpaceAttri: TSynHighlighterAttributes; fStringAttri: TSynHighlighterAttributes; fSymbolAttri: TSynHighlighterAttributes; - FFoldConfig: Array [TLfmCodeFoldBlockType] of TSynCustomFoldConfig; procedure AltProc; procedure AsciiCharProc; procedure BraceCloseProc; @@ -120,8 +120,6 @@ type procedure SymbolProc; procedure UnknownProc; procedure MakeMethodTables; - procedure InitFoldConfig; - procedure DestroyFoldConfig; protected function GetIdentChars: TSynIdentChars; override; function GetSampleSource: string; override; @@ -134,9 +132,9 @@ type procedure EndLfmCodeFoldBlock; function TopLfmCodeFoldBlockType(DownIndex: Integer = 0): TLfmCodeFoldBlockType; protected - function GetFoldConfig(Index: Integer): TSynCustomFoldConfig; override; + function GetFoldConfigInstance(Index: Integer): TSynCustomFoldConfig; override; function GetFoldConfigCount: Integer; override; - procedure SetFoldConfig(Index: Integer; const AValue: TSynCustomFoldConfig); override; + function GetFoldConfigInternalCount: Integer; override; public {$IFNDEF SYN_CPPB_1} class {$ENDIF} //mh 2000-07-14 function GetLanguageName: string; override; @@ -290,29 +288,15 @@ begin end; end; -procedure TSynLFMSyn.InitFoldConfig; -var - i: TLfmCodeFoldBlockType; +function TSynLFMSyn.GetFoldConfigInstance(Index: Integer): TSynCustomFoldConfig; 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; + Result := inherited GetFoldConfigInstance(Index); + Result.Enabled := True; end; constructor TSynLFMSyn.Create(AOwner: TComponent); begin inherited Create(AOwner); - InitFoldConfig; fCommentAttri := TSynHighlighterAttributes.Create(SYNS_AttrComment, SYNS_XML_AttrComment); fCommentAttri.Style := [fsItalic]; AddAttribute(fCommentAttri); @@ -337,7 +321,6 @@ end; destructor TSynLFMSyn.Destroy; begin - DestroyFoldConfig; inherited Destroy; end; @@ -643,16 +626,19 @@ end; function TSynLFMSyn.FoldOpenCount(ALineIndex: Integer; AType: Integer): integer; begin + If AType <> 0 then exit(0); Result := EndFoldLevel(ALineIndex) - MinimumFoldLevel(ALineIndex); end; function TSynLFMSyn.FoldCloseCount(ALineIndex: Integer; AType: Integer): integer; begin + If AType <> 0 then exit(0); Result := EndFoldLevel(ALineIndex - 1) - MinimumFoldLevel(ALineIndex); end; function TSynLFMSyn.FoldNestCount(ALineIndex: Integer; AType: Integer): integer; begin + If AType <> 0 then exit(0); Result := EndFoldLevel(ALineIndex); end; @@ -740,7 +726,7 @@ var FoldBlock: Boolean; p: PtrInt; begin - FoldBlock := FFoldConfig[ABlockType].Enabled; + FoldBlock := FFoldConfig[ord(ABlockType)].Enabled; p := 0; if not FoldBlock then p := PtrInt(CountLfmCodeFoldBlockOffset); @@ -760,24 +746,16 @@ begin Result := TLfmCodeFoldBlockType(PtrUInt(TopCodeFoldBlockType(DownIndex))); 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; + // excluded cfbtLfmNone Result := ord(high(TLfmCodeFoldBlockType)) - ord(low(TLfmCodeFoldBlockType)); end; -procedure TSynLFMSyn.SetFoldConfig(Index: Integer; const AValue: TSynCustomFoldConfig); +function TSynLFMSyn.GetFoldConfigInternalCount: Integer; begin - BeginUpdate; - FFoldConfig[TLfmCodeFoldBlockType(Index + 1)].Assign(AValue); - EndUpdate; - // Todo: Since all synedits will rescan => delete all foldranges + // include cfbtLfmNone + Result := ord(high(TLfmCodeFoldBlockType)) - ord(low(TLfmCodeFoldBlockType)) + 1; end; {$IFNDEF SYN_CPPB_1} //mh 2000-07-14 diff --git a/components/synedit/synhighlighterpas.pp b/components/synedit/synhighlighterpas.pp index 96a3e27e10..07992a6531 100644 --- a/components/synedit/synhighlighterpas.pp +++ b/components/synedit/synhighlighterpas.pp @@ -90,7 +90,6 @@ type type {$IFDEF SYN_LAZARUS} TPascalCodeFoldBlockType = ( - cfbtNone, cfbtBeginEnd, // Nested cfbtTopBeginEnd, // Begin of Procedure cfbtNestedComment, @@ -110,7 +109,9 @@ type cfbtAsm, cfbtCase, cfbtIfDef, // {$IfDef} directive, ths is not counted in the Range-Node - cfbtRegion // {%Region} user folds, not counted in the Range-Node + cfbtRegion, // {%Region} user folds, not counted in the Range-Node + // Internal type / not configurable + cfbtNone ); TPascalCodeFoldBlockTypes = set of TPascalCodeFoldBlockType; @@ -271,7 +272,6 @@ type FNodeInfoLine, FNodeInfoCount: Integer; FNodeInfoList: Array of TSynFoldNodeInfo; FDividerDrawConfig: Array [TSynPasDividerDrawLocation] of TSynDividerDrawConfig; - FFoldConfig: Array [TPascalCodeFoldBlockType] of TSynCustomFoldConfig; procedure GrowNodeInfoList; function GetPasCodeFoldRange: TSynPasSynRange; procedure SetCompilerMode(const AValue: TPascalCompilerMode); @@ -408,8 +408,6 @@ type ABlockType: TPascalCodeFoldBlockType; aActions: TSynFoldActions); procedure CreateDividerDrawConfig; procedure DestroyDividerDrawConfig; - procedure InitFoldConfig; - procedure DestroyFoldConfig; protected function GetIdentChars: TSynIdentChars; override; function IsFilterStored: boolean; override; //mh 2000-10-08 @@ -444,9 +442,9 @@ type function GetDividerDrawConfig(Index: Integer): TSynDividerDrawConfig; override; function GetDividerDrawConfigCount: Integer; override; - function GetFoldConfig(Index: Integer): TSynCustomFoldConfig; override; + function GetFoldConfigInstance(Index: Integer): TSynCustomFoldConfig; override; function GetFoldConfigCount: Integer; override; - procedure SetFoldConfig(Index: Integer; const AValue: TSynCustomFoldConfig); override; + function GetFoldConfigInternalCount: Integer; override; public {$IFNDEF SYN_CPPB_1} class {$ENDIF} function GetCapabilities: TSynHighlighterCapabilities; override; @@ -2020,7 +2018,6 @@ constructor TSynPasSyn.Create(AOwner: TComponent); begin inherited Create(AOwner); CreateDividerDrawConfig; - InitFoldConfig; fD4syntax := true; fAsmAttri := TSynHighlighterAttributes.Create(SYNS_AttrAssembler, SYNS_XML_AttrAssembler); AddAttribute(fAsmAttri); @@ -2059,7 +2056,6 @@ end; { Create } destructor TSynPasSyn.Destroy; begin DestroyDividerDrawConfig; - DestroyFoldConfig; inherited Destroy; end; @@ -3060,7 +3056,7 @@ end; procedure TSynPasSyn.StartCustomCodeFoldBlock(ABlockType: TPascalCodeFoldBlockType); begin - if not FFoldConfig[ABlockType].Enabled then exit; + if not FFoldConfig[ord(ABlockType)].Enabled then exit; if FCatchNodeInfo then begin // exclude subblocks, because they do not increase the foldlevel yet GrowNodeInfoList; InitNode(FNodeInfoList[FNodeInfoCount], +1, ABlockType, [sfaOpen, sfaFold]); @@ -3076,7 +3072,7 @@ end; procedure TSynPasSyn.EndCustomCodeFoldBlock(ABlockType: TPascalCodeFoldBlockType); begin - if not FFoldConfig[ABlockType].Enabled then exit; + if not FFoldConfig[ord(ABlockType)].Enabled then exit; if FCatchNodeInfo then begin // exclude subblocks, because they do not increase the foldlevel yet GrowNodeInfoList; InitNode(FNodeInfoList[FNodeInfoCount], -1, ABlockType, [sfaClose, sfaFold]); @@ -3108,7 +3104,7 @@ var FoldBlock: Boolean; act: TSynFoldActions; begin - FoldBlock := FFoldConfig[ABlockType].Enabled; + FoldBlock := FFoldConfig[ord(ABlockType)].Enabled; p := 0; if FCatchNodeInfo then begin // exclude subblocks, because they do not increase the foldlevel yet GrowNodeInfoList; @@ -3360,26 +3356,14 @@ begin FreeAndNil(FDividerDrawConfig[i]); end; -procedure TSynPasSyn.InitFoldConfig; -var - i: TPascalCodeFoldBlockType; +function TSynPasSyn.GetFoldConfigInstance(Index: Integer): TSynCustomFoldConfig; begin - for i := low(TPascalCodeFoldBlockType) to high(TPascalCodeFoldBlockType) do begin - FFoldConfig[i] := TSynCustomFoldConfig.Create; - FFoldConfig[i].OnChange := @DoFoldConfigChanged; - FFoldConfig[i].Enabled := i in [cfbtBeginEnd, cfbtTopBeginEnd, cfbtNestedComment, - cfbtProcedure, cfbtUses, cfbtLocalVarType, cfbtClass, - cfbtClassSection, cfbtRecord, cfbtRepeat, cfbtCase, - cfbtAsm, cfbtRegion]; - end; -end; - -procedure TSynPasSyn.DestroyFoldConfig; -var - i: TPascalCodeFoldBlockType; -begin - for i := low(TPascalCodeFoldBlockType) to high(TPascalCodeFoldBlockType) do - FFoldConfig[i].Free; + Result := inherited GetFoldConfigInstance(Index); + Result.Enabled := TPascalCodeFoldBlockType(Index) in + [cfbtBeginEnd, cfbtTopBeginEnd, cfbtNestedComment, + cfbtProcedure, cfbtUses, cfbtLocalVarType, cfbtClass, + cfbtClassSection, cfbtRecord, cfbtRepeat, cfbtCase, + cfbtAsm, cfbtRegion]; end; function TSynPasSyn.CreateRangeList: TSynHighlighterRangeList; @@ -3401,12 +3385,6 @@ begin TSynHighlighterPasRangeList(CurrentRanges).PasRangeInfo[Index] := FSynPasRangeInfo; end; -function TSynPasSyn.GetFoldConfig(Index: Integer): TSynCustomFoldConfig; -begin - // + 1 as we skip cfbtNone; - Result := FFoldConfig[TPascalCodeFoldBlockType(Index + 1)]; -end; - function TSynPasSyn.GetFoldConfigCount: Integer; begin // excluded cfbtNone; @@ -3414,12 +3392,12 @@ begin ord(low(TPascalCodeFoldBlockType)); end; -procedure TSynPasSyn.SetFoldConfig(Index: Integer; const AValue: TSynCustomFoldConfig); +function TSynPasSyn.GetFoldConfigInternalCount: Integer; begin - BeginUpdate; - FFoldConfig[TPascalCodeFoldBlockType(Index + 1)].Assign(AValue); - EndUpdate; - // Todo: Since all synedits will rescan => delete all foldranges + // include cfbtNone; + Result := ord(high(TPascalCodeFoldBlockType)) - + ord(low(TPascalCodeFoldBlockType)) + + 1; end; function TSynPasSyn.GetDividerDrawConfig(Index: Integer): TSynDividerDrawConfig; diff --git a/components/synedit/synhighlighterxml.pas b/components/synedit/synhighlighterxml.pas index f9ef7afdb0..00c0a921f5 100644 --- a/components/synedit/synhighlighterxml.pas +++ b/components/synedit/synhighlighterxml.pas @@ -60,14 +60,10 @@ uses {$IFDEF SYN_CLX} Qt, QControls, QGraphics, {$ELSE} - {$IFDEF SYN_LAZARUS} - LCLIntf, LCLType, - {$ELSE} - Windows, Messages, Registry, + Graphics, {$ENDIF} - Controls, Graphics, - {$ENDIF} - SynEditTypes, SynEditTextBuffer, SynEditHighlighter, SynEditHighlighterFoldBase; + SynEditTypes, SynEditTextBuffer, SynEditHighlighter, + SynEditHighlighterFoldBase, SynEditHighlighterXMLBase; type TtkTokenKind = (tkAposAttrValue, tkAposEntityRef, tkAttribute, tkCDATA, @@ -97,25 +93,17 @@ type ); TXmlCodeFoldBlockType = ( - cfbtXmlNone, cfbtXmlNode, // ... cfbtXmlComment, // cfbtXmlCData, // cfbtXmlDocType, // FXmlRangeInfoOpenPos; - InfoCloseLenChanged := Length(FXmlRangeInfo.ElementCloseList) <> FXmlRangeInfoClosePos; - if FXmlRangeInfoChanged or InfoOpenLenChanged or InfoCloseLenChanged then begin - Result := True; - if InfoOpenLenChanged then - SetLength(FXmlRangeInfo.ElementOpenList, FXmlRangeInfoOpenPos); - if InfoCloseLenChanged then - SetLength(FXmlRangeInfo.ElementCloseList, FXmlRangeInfoClosePos); - TSynHighlighterXmlRangeList(CurrentRanges).XmlRangeInfo[LineIndex] := FXmlRangeInfo; // Store on this line - FXmlRangeInfoChanged := False; - end; + Result := inherited GetFoldConfigInstance(Index); + Result.Enabled := True; end; procedure TSynXMLSyn.IdentProc; @@ -1029,67 +954,6 @@ begin fRange:= rsText; end; -function TSynXMLSyn.FoldOpenCount(ALineIndex: Integer; AType: Integer): integer; -begin - Result := EndFoldLevel(ALineIndex) - MinimumFoldLevel(ALineIndex); -end; - -function TSynXMLSyn.FoldCloseCount(ALineIndex: Integer; AType: Integer): integer; -begin - Result := EndFoldLevel(ALineIndex - 1) - MinimumFoldLevel(ALineIndex); -end; - -function TSynXMLSyn.FoldNestCount(ALineIndex: Integer; AType: Integer): integer; -begin - Result := EndFoldLevel(ALineIndex); -end; - -function TSynXMLSyn.FoldLineLength(ALineIndex, FoldIndex: Integer): integer; -var - i, lvl, cnt: Integer; - e, m: Integer; -begin - //atype := FoldTypeAtNodeIndex(ALineIndex, FoldIndex); - cnt := CurrentLines.Count; - e := EndFoldLevel(ALineIndex); - m := MinimumFoldLevel(ALineIndex); - lvl := Min(m+1+FoldIndex, e); - i := ALineIndex + 1; - while (i < cnt) and (MinimumFoldLevel(i) >= lvl) do inc(i); - // check if fold last line of block (not mixed "end begin") - // and not lastlinefix - if (i = cnt) or (EndFoldLevel(i) > MinimumFoldLevel(i)) then - dec(i); - // Amount of lines, that will become invisible (excludes the cfCollapsed line) - Result := i - ALineIndex; -end; - -function TSynXMLSyn.MinimumFoldLevel(ALineIndex: Integer): integer; -var - r: TSynCustomHighlighterRange; -begin - if (ALineIndex < 0) or (ALineIndex >= CurrentLines.Count) then - exit(0); - r := TSynCustomHighlighterRange(CurrentRanges[ALineIndex]); - if (r <> nil) and (Pointer(r) <> NullRange) then - Result := r.MinimumCodeFoldBlockLevel - else - Result := 0; -end; - -function TSynXMLSyn.EndFoldLevel(ALineIndex: Integer): integer; -var - r: TSynCustomHighlighterRange; -begin - if (ALineIndex < 0) or (ALineIndex >= CurrentLines.Count) then - exit(0); - r := TSynCustomHighlighterRange(CurrentRanges[ALineIndex]); - if (r <> nil) and (Pointer(r) <> NullRange) then - Result := r.CodeFoldStackSize - else - Result := 0; -end; - function TSynXMLSyn.GetIdentChars: TSynIdentChars; begin Result := ['0'..'9', 'a'..'z', 'A'..'Z', '_', '.', '-'] + TSynSpecialChars; @@ -1118,124 +982,22 @@ begin RootCodeFoldBlock.InitRootBlockType(Pointer(PtrInt(cfbtXmlNone))); end; -function TSynXMLSyn.CreateRangeList: TSynHighlighterRangeList; -begin - Result := TSynHighlighterXmlRangeList.Create; -end; - function TSynXMLSyn.StartXmlCodeFoldBlock(ABlockType: TXmlCodeFoldBlockType): TSynCustomCodeFoldBlock; -var - FoldBlock: Boolean; - p: PtrInt; begin - FoldBlock := FFoldConfig[ABlockType].Enabled; - p := 0; - if not FoldBlock then - p := PtrInt(CountXmlCodeFoldBlockOffset); - Result := StartCodeFoldBlock(p + Pointer(PtrInt(ABlockType)), FoldBlock); + Result := inherited StartXmlCodeFoldBlock(ord(ABlockType)); end; function TSynXMLSyn.StartXmlNodeCodeFoldBlock(ABlockType: TXmlCodeFoldBlockType; OpenPos: Integer; AName: String): TSynCustomCodeFoldBlock; -var - i: Integer; begin - if not FFoldConfig[cfbtXmlNode].Enabled then exit; - If IsScanning then begin - AName := LowerCase(AName); - i := Length(FXmlRangeInfo.ElementOpenList); - if (FXmlRangeInfoOpenPos < i) then begin - if (FXmlRangeInfo.ElementOpenList[FXmlRangeInfoOpenPos] <> AName) then begin - FXmlRangeInfo.ElementOpenList[FXmlRangeInfoOpenPos] := AName; - FXmlRangeInfoChanged := true; // TODO:if this node closes on the same line, it may not be amodified .... - end; - end else begin // append - modified will be deteced by the new length - SetLength(FXmlRangeInfo.ElementOpenList, FXmlRangeInfoOpenPos + 10); - FXmlRangeInfo.ElementOpenList[FXmlRangeInfoOpenPos] := AName; - end; - end; - inc(FXmlRangeInfoOpenPos); - result := StartXmlCodeFoldBlock(ABlockType); + if not FFoldConfig[ord(cfbtXmlNode)].Enabled then exit; + Result := inherited StartXmlNodeCodeFoldBlock(ord(ABlockType), OpenPos, AName); end; -procedure TSynXMLSyn.EndXmlCodeFoldBlock; -var - DecreaseLevel: Boolean; +procedure TSynXMLSyn.EndXmlNodeCodeFoldBlock(ClosePos: Integer; AName: String); begin - DecreaseLevel := TopCodeFoldBlockType < CountXmlCodeFoldBlockOffset; - EndCodeFoldBlock(DecreaseLevel); -end; - -procedure TSynXMLSyn.EndXmlNodeCodeFoldBlock(ClosePos: Integer = -1; AName: String = ''); -var - cnt, i, k, lvl: Integer; - LInfo: Array of String; -begin - if not FFoldConfig[cfbtXmlNode].Enabled then exit; - AName := LowerCase(AName); - - cnt := 0; - If IsScanning then begin - if (AName = '') and (CodeFoldRange.CodeFoldStackSize > 0) then begin - cnt := 1; - end - else begin - cnt := 1; - i := FXmlRangeInfoOpenPos; - while i > 0 do begin - if (FXmlRangeInfo.ElementOpenList[i-1] = AName) then - break; - dec(i); - inc(cnt); - end; - - if i = 0 then begin - i := LineIndex - 1; - lvl := EndFoldLevel(i); - while i >= 0 do begin - if MinimumFoldLevel(i) < lvl then begin - LInfo := TSynHighlighterXmlRangeList(CurrentRanges).XmlRangeInfo[i].ElementOpenList; - k := length(LInfo) - Max(EndFoldLevel(i) - lvl, 0) - 1; - while (k >= 0) do begin - if (LInfo[k] = AName) then - break; - inc(cnt); - dec(k); - dec(lvl); - end; - if k >= 0 then break; - end; - dec(i); - end; - - if (i < 0) or (cnt > CodeFoldRange.CodeFoldStackSize ) then cnt := 0; // never opened, do not close - end; - end; - - i := Length(FXmlRangeInfo.ElementCloseList); - if (FXmlRangeInfoClosePos < i) then begin - if (FXmlRangeInfo.ElementCloseList[FXmlRangeInfoClosePos] <> cnt) then begin - FXmlRangeInfo.ElementCloseList[FXmlRangeInfoClosePos] := cnt; - FXmlRangeInfoChanged := true; - end; - end else begin // append - modified will be deteced by the new length - SetLength(FXmlRangeInfo.ElementCloseList, FXmlRangeInfoClosePos + 10); - FXmlRangeInfo.ElementCloseList[FXmlRangeInfoClosePos] := cnt; - end; - end - else begin - if FXmlRangeInfoClosePos < length(FXmlRangeInfo.ElementCloseList) then - cnt := FXmlRangeInfo.ElementCloseList[FXmlRangeInfoClosePos] - else - cnt := 0; - end; - inc(FXmlRangeInfoClosePos); - - for i := 1 to cnt do begin - if FXmlRangeInfoOpenPos > 0 then - dec(FXmlRangeInfoOpenPos); - EndXmlCodeFoldBlock; - end; + if not FFoldConfig[ord(cfbtXmlNode)].Enabled then exit; + inherited EndXmlNodeCodeFoldBlock(ClosePos, AName); end; function TSynXMLSyn.TopXmlCodeFoldBlockType(DownIndex: Integer): TXmlCodeFoldBlockType; @@ -1243,24 +1005,16 @@ begin Result := TXmlCodeFoldBlockType(PtrUInt(TopCodeFoldBlockType(DownIndex))); 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; + // excluded cfbtXmlNone Result := ord(high(TXmlCodeFoldBlockType)) - ord(low(TXmlCodeFoldBlockType)); end; -procedure TSynXMLSyn.SetFoldConfig(Index: Integer; const AValue: TSynCustomFoldConfig); +function TSynXMLSyn.GetFoldConfigInternalCount: Integer; begin - BeginUpdate; - FFoldConfig[TXmlCodeFoldBlockType(Index + 1)].Assign(AValue); - EndUpdate; - // Todo: Since all synedits will rescan => delete all foldranges + // excluded cfbtXmlNone; + Result := ord(high(TXmlCodeFoldBlockType)) - ord(low(TXmlCodeFoldBlockType)) + 1; end; { TSynHighlighterXmlRangeList }