diff --git a/Components/ScintEdit.pas b/Components/ScintEdit.pas index 81631e1d2..e1b3b5ddc 100644 --- a/Components/ScintEdit.pas +++ b/Components/ScintEdit.pas @@ -451,8 +451,8 @@ TScintCustomStyler = class(TComponent) function ConsumeString(const Chars: TScintRawCharSet): TScintRawString; function CurCharIn(const Chars: TScintRawCharSet): Boolean; function CurCharIs(const C: AnsiChar): Boolean; - procedure GetFoldLevel(const LineState: TScintLineState; var Level: Integer; - var Header: Boolean); virtual; abstract; + procedure GetFoldLevel(const LineState, NextLineState: TScintLineState; + var Level: Integer; var Header: Boolean); virtual; abstract; procedure GetStyleAttributes(const Style: Integer; var Attributes: TScintStyleAttributes); virtual; abstract; function LineTextSpans(const S: TScintRawString): Boolean; virtual; @@ -1843,26 +1843,11 @@ procedure TScintEdit.StyleNeeded(const EndPos: Integer); FStyler.FStyleStr := ''; FStyler.FText := ''; end; - - var FoldLevel: Integer; - var FoldHeader: Boolean; - FStyler.GetFoldLevel(FStyler.FLineState, FoldLevel, FoldHeader); - Inc(FoldLevel, SC_FOLDLEVELBASE); - if FoldHeader then - FoldLevel := FoldLevel or SC_FOLDLEVELHEADERFLAG; - { Setting SC_FOLDLEVELWHITEFLAG on empty lines causes a problem: when - Scintilla auto expands a contracted section (for example after removing ']' - from a section header) all the empty lines stay invisible, even any which - are in the middle of the section. } - + for var I := FirstLine to LastLine do begin var OldState := FLines.GetState(I); if FStyler.FLineState <> OldState then Call(SCI_SETLINESTATE, I, FStyler.FLineState); - { To display/debug fold levels use: FoldFlags := [sffLevelNumbers]; } - var OldLevel := Call(SCI_GETFOLDLEVEL, I, 0); - if FoldLevel <> OldLevel then - Call(SCI_SETFOLDLEVEL, I, FoldLevel); end; Result := LastLine; @@ -1878,6 +1863,29 @@ procedure TScintEdit.StyleNeeded(const EndPos: Integer); Call(SCI_SETSTYLINGEX, Length(StyleStr), LPARAM(PAnsiChar(StyleStr))); end; + procedure FoldLine(const Line, EndLine: Integer); + begin + var LineState := FLines.GetState(Line); + var NextLineState: TScintLineState := 0; + if Line < EndLine then + NextLineState := FLines.GetState(Line+1); + + var FoldLevel: Integer; + var FoldHeader: Boolean; + FStyler.GetFoldLevel(LineState, NextLineState, FoldLevel, FoldHeader); + Inc(FoldLevel, SC_FOLDLEVELBASE); + if FoldHeader then + FoldLevel := FoldLevel or SC_FOLDLEVELHEADERFLAG; + { Setting SC_FOLDLEVELWHITEFLAG on empty lines causes a problem: when + Scintilla auto expands a contracted section (for example after removing ']' + from a section header) all the empty lines stay invisible, even any which + are in the middle of the section. } + + var OldLevel := Call(SCI_GETFOLDLEVEL, Line, 0); + if FoldLevel <> OldLevel then + Call(SCI_SETFOLDLEVEL, Line, FoldLevel); + end; + var StartPos, StartLine, EndLine, Line: Integer; begin @@ -1915,6 +1923,14 @@ procedure TScintEdit.StyleNeeded(const EndPos: Integer); DefaultStyleLine(Line); Inc(Line); end; + + if Assigned(FStyler) then begin + Line := StartLine; + while Line <= EndLine do begin + FoldLine(Line, EndLine); + Inc(Line); + end; + end; end; procedure TScintEdit.SysColorChange(const Message: TMessage); diff --git a/Components/ScintStylerInnoSetup.pas b/Components/ScintStylerInnoSetup.pas index eee3356de..3f6bfae9a 100644 --- a/Components/ScintStylerInnoSetup.pas +++ b/Components/ScintStylerInnoSetup.pas @@ -105,8 +105,8 @@ TInnoSetupStyler = class(TScintCustomStyler) procedure SetISPPInstalled(const Value: Boolean); protected procedure CommitStyle(const Style: TInnoSetupStylerStyle); - procedure GetFoldLevel(const LineState: TScintLineState; var Level: Integer; - var Header: Boolean); override; + procedure GetFoldLevel(const LineState, NextLineState: TScintLineState; + var Level: Integer; var Header: Boolean); override; procedure GetStyleAttributes(const Style: Integer; var Attributes: TScintStyleAttributes); override; function LineTextSpans(const S: TScintRawString): Boolean; override; @@ -937,31 +937,22 @@ function TInnoSetupStyler.GetFlagsWordList(Section: TInnoSetupStylerSection): An Result := FFlagsWordList[Section]; end; -procedure TInnoSetupStyler.GetFoldLevel(const LineState: TScintLineState; +procedure TInnoSetupStyler.GetFoldLevel(const LineState, NextLineState: TScintLineState; var Level: Integer; var Header: Boolean); begin - { Set folding per section. To keep our code as simple as possible we simply - give all lines outside of a section (=lines at the start of the document and - section tags and section end tags and lines after section end tags) a header - flag. This avoids having to look at the previous line. Doesn't mean - Scintilla will display folding markers on all these header lines: it only - does that when there is something to fold, so when the header line is - followed a by non-header line which is only the case for a section tag line - followed by a section line. - - Did notice an issue (Scintilla automatic folding bug?): Add a section with - some lines. Contract it. Break the section header for example by removing ']'. - Scintialla now auto expands the section and removes the fold mark. - Retype the ']'. Scintilla now displays the old fold mark to expand the - section but it's already expanded. } + { Set folding per section. Lines outside of a section (=lines at the start of + the document and section tags and section end tags and lines after section + end tags) get level 0 with header flags for section tags. Other lines + (=lines inside a section) get level 1. } var Section := TInnoSetupStyler.GetSectionFromLineState(LineState); - if Section <> scNone then begin + if Section = scNone then begin + Level := 0; + var NextSection := TInnoSetupStyler.GetSectionFromLineState(NextLineState); + Header := NextSection <> scNone; + end else begin Level := 1; Header := False; - end else begin - Level := 0; - Header := True; end; end;