Skip to content

Commit

Permalink
Cleanup folding method. Avoids header flags on lines which shouldn't …
Browse files Browse the repository at this point in the history
…really have them. Seems to fix the mentioned issue.
  • Loading branch information
martijnlaan committed Jun 19, 2024
1 parent e38fbf7 commit 4ecfe56
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 39 deletions.
52 changes: 34 additions & 18 deletions Components/ScintEdit.pas
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -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);
Expand Down
33 changes: 12 additions & 21 deletions Components/ScintStylerInnoSetup.pas
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down

0 comments on commit 4ecfe56

Please sign in to comment.