Synedit/IDE: Added hiding of comment/region

git-svn-id: trunk@26814 -
This commit is contained in:
martin 2010-07-24 16:59:04 +00:00
parent 8100a2780c
commit 86a9620e2c
11 changed files with 1663 additions and 781 deletions

View File

@ -448,6 +448,7 @@ type
FOnSpecialLineMarkup: TSpecialLineMarkupEvent;// needed, because bug fpc 11926
FOnClickLink: TMouseEvent;
FOnMouseLink: TSynMouseLinkEvent;
FPendingFoldState: String;
procedure AquirePrimarySelection;
function GetChangeStamp: int64;
@ -2990,10 +2991,15 @@ begin
if (iLine<=0) or (iLine>FTheLinesView.Count) then exit;
dec(iLine);
//DebugLn(['****** FoldAction at ',iLine,' scrline=',FFoldedLinesView.TextIndexToScreenLine(iLine), ' type ', SynEditCodeFoldTypeNames[FFoldedLinesView.FoldType[FFoldedLinesView.TextIndexToScreenLine(iLine)]], ' view topline=',FFoldedLinesView.TopLine ]);
case FFoldedLinesView.FoldType[FFoldedLinesView.TextIndexToScreenLine(iLine)] of
cfCollapsed : FFoldedLinesView.UnFoldAtTextIndex(iLine);
cfExpanded : FFoldedLinesView.FoldAtTextIndex(iLine);
end;
if FFoldedLinesView.FoldType[FFoldedLinesView.TextIndexToScreenLine(iLine)]
* [cfCollapsedFold, cfCollapsedHide] <> []
then
FFoldedLinesView.UnFoldAtTextIndex(iLine)
else
if FFoldedLinesView.FoldType[FFoldedLinesView.TextIndexToScreenLine(iLine)]
* [cfFoldStart] <> []
then
FFoldedLinesView.FoldAtTextIndex(iLine);
end;
function TCustomSynEdit.FindNextUnfoldedLine(iLine: integer; Down: boolean
@ -3001,9 +3007,12 @@ function TCustomSynEdit.FindNextUnfoldedLine(iLine: integer; Down: boolean
// iLine is 1 based
begin
Result:=iLine;
while (Result>0) and (Result<=FTheLinesView.Count)
and (FFoldedLinesView.FoldedAtTextIndex[Result-1]) do
if Down then inc(Result) else dec(Result);
if Down then
while (Result<FTheLinesView.Count) and (FFoldedLinesView.FoldedAtTextIndex[Result-1]) do
inc(Result)
else
while (Result>1) and (FFoldedLinesView.FoldedAtTextIndex[Result-1]) do
dec(Result);
end;
function TCustomSynEdit.CreateGutter(AOwner : TSynEditBase;
@ -3317,7 +3326,7 @@ var
LCLIntf.LineTo(dc, nRightEdge, rcLine.Bottom + 1);
end;
if FFoldedLinesView.FoldType[CurLine] = cfCollapsed then
if FFoldedLinesView.FoldType[CurLine] * [cfCollapsedFold, cfCollapsedHide] <> [] then
begin
FillFCol := Font.Color;
FillBCol := colEditorBG;
@ -4209,6 +4218,9 @@ begin
Value := Max(Value, 1);
if FFoldedLinesView.FoldedAtTextIndex[Value-1] then
Value := FindNextUnfoldedLine(Value, False);
if FFoldedLinesView.FoldedAtTextIndex[Value-1] then
Value := FindNextUnfoldedLine(Value, True);
Value := Min(Value, CurrentMaxTopLine);
FFoldedLinesView.TopTextIndex := fTopLine - 1;
if Value <> fTopLine then begin
fTopLine := Value;
@ -4757,6 +4769,8 @@ begin
InvalidateLines(AIndex + 1, AIndex + 1 + ACount);
InvalidateGutterLines(AIndex + 1, AIndex + 1 + ACount);
FFoldedLinesView.FixFoldingAtTextIndex(AIndex, AIndex + ACount);
if FPendingFoldState <> '' then
SetFoldState(FPendingFoldState);
end;
procedure TCustomSynEdit.ListCleared(Sender: TObject);
@ -4789,8 +4803,8 @@ begin
if eoAlwaysVisibleCaret in fOptions2 then
MoveCaretToVisibleArea;
UpdateScrollBars;
if Index + 1 > ScreenRowToRow(LinesInWindow + 1) then exit;
if Index + 1 < TopLine then Index := TopLine;
if Index + 1 > Max(1, ScreenRowToRow(LinesInWindow + 1)) then exit;
if Index + 1 < TopLine then Index := TopLine - 1;
InvalidateLines(Index + 1, -1);
InvalidateGutterLines(Index + 1, -1);
end;
@ -5093,10 +5107,22 @@ end;
procedure TCustomSynEdit.SetFoldState(const AValue: String);
begin
if assigned(fHighlighter) then begin
fHighlighter.CurrentLines := FTheLinesView;
if fHighlighter.NeedScan then begin
FPendingFoldState := AValue;
exit;
end;
end;
if sfAfterLoadFromFileNeeded in fStateFlags then begin
FPendingFoldState := AValue;
exit;
end;
FFoldedLinesView.Lock;
FFoldedLinesView.ApplyFoldDescription(0, 0, -1, -1, PChar(AValue), length(AValue), True);
TopLine := TopLine; // Todo: reset topline on foldedview
FFoldedLinesView.UnLock;
FPendingFoldState := '';
end;
procedure TCustomSynEdit.SetMouseActions(const AValue: TSynEditMouseActions);
@ -5555,6 +5581,7 @@ end;
procedure TCustomSynEdit.SetHighlighter(const Value: TSynCustomHighlighter);
begin
if Value <> fHighlighter then begin
FPendingFoldState := '';
RemoveHooksFromHighlighter;
if Assigned(Value) then begin
Value.HookAttrChangeEvent(
@ -5944,7 +5971,7 @@ begin
end;
ecEditorTop, ecSelEditorTop:
begin
FCaret.LineCharPos := Point(1, 1);
FCaret.LineCharPos := Point(1, FFoldedLinesView.ViewPosToTextIndex(1)+1);
end;
ecEditorBottom, ecSelEditorBottom:
begin
@ -5955,7 +5982,7 @@ begin
end;
ecColSelEditorTop:
begin
FCaret.LinePos := 1;
FCaret.LinePos := FFoldedLinesView.ViewPosToTextIndex(1)+1;
end;
ecColSelEditorBottom:
begin
@ -6517,6 +6544,8 @@ begin
ScanRanges;
FFoldedLinesView.UnfoldAll;
FFoldedLinesView.CollapseDefaultFolds;
if FPendingFoldState <> '' then
SetFoldState(FPendingFoldState);
TopLine := TopLine;
end;
end;

File diff suppressed because it is too large Load Diff

View File

@ -312,6 +312,7 @@ type
procedure ScanRanges;
function IdleScanRanges: Boolean; // Scan little by little during OnIdle; Return True, if more work avail
function NeedScan: Boolean;
procedure ScanAllRanges;
procedure SetRange(Value: Pointer); virtual;
procedure ResetRange; virtual;
@ -1299,7 +1300,9 @@ begin
end;
StartIndex := CurrentRanges.NeedsReScanRealStartIndex; // include idle scanned
CurrentRanges.ClearReScanNeeded;
CurrentLines.SendHighlightChanged(StartIndex, EndIndex - StartIndex + 1);
// Invalidate one line above, since folds can change depending on next line
// TODO: only classes with end-fold-last-line
CurrentLines.SendHighlightChanged(StartIndex - 1, EndIndex - StartIndex + 1);
end;
function TSynCustomHighlighter.IdleScanRanges: Boolean;
@ -1326,7 +1329,8 @@ begin
StartIndex := CurrentRanges.NeedsReScanRealStartIndex; // include idle scanned
//debugln(['=== IDLE SendHighlightChanged ',StartIndex,' - ',EndIndex]);
CurrentRanges.ClearReScanNeeded;
CurrentLines.SendHighlightChanged(StartIndex, EndIndex - StartIndex + 1);
// Invalidate one line above, since folds can change depending on next line
CurrentLines.SendHighlightChanged(StartIndex - 1, EndIndex - StartIndex + 1);
exit;
end
else begin
@ -1335,6 +1339,11 @@ begin
end;
end;
function TSynCustomHighlighter.NeedScan: Boolean;
begin
Result := (CurrentRanges.NeedsReScanStartIndex >= 0);
end;
function TSynCustomHighlighter.PerformScan(StartIndex, EndIndex: Integer;
ForceEndIndex: Boolean = False): Integer;
var

View File

@ -37,20 +37,58 @@ uses
type
TSynFoldAction = (sfaOpen, // At this node a new Fold can start
sfaClose, // At this node a fold ends
sfaMarkup, // This node can be highlighted, by the matching Word-Pair Markup
sfaFold, // Part of a fold- or hide-able block (FoldConf.Enabled = True)
sfaFoldFold, // Part of a fold-able block (FoldConf.Enabled = True / smFold in Modes)
sfaFoldHide, // Part of a hide-able block (FoldConf.Enabled = True / smHide in Modes)
sfaInvalid, // Wrong Index
sfaDefaultCollapsed,
sfaOneLineOpen, // Open, but closes on same line; *only* if hide-able has [sfaOpen, sfaFold]; always has [sfaFoldFold, sfaFoldHide]
sfaOneLineClose, // Open, but closes on same line;
sfaLastLineClose // Fold is incomplete, and closed at last line of file
);
TSynFoldActions = set of TSynFoldAction;
TSynFoldNodeInfo = record
LineIndex: Integer;
NodeIndex: Integer; // Indicates the position within the list of info nodes (depends on search-Filter)
LogXStart, LogXEnd: Integer; // -1 previous line
FoldLvlStart, FoldLvlEnd: Integer; // FoldLvl within each FoldGroup
NestLvlStart, NestLvlEnd: Integer; // include disabled nodes, e.g markup (within each FoldGroup)
FoldAction: TSynFoldActions;
FoldType: Pointer; // e.g.cfbtBeginEnd, cfbtcfbtProcedure ...
FoldGroup: Integer; // independend/overlapping folds, e.g begin/end; ifdef, region
end;
TSynCustomFoldConfigMode = (fmFold, fmHide);
TSynCustomFoldConfigModes = set of TSynCustomFoldConfigMode;
{ TSynCustomFoldConfig }
TSynCustomFoldConfig = class(TPersistent)
private
FEnabled: Boolean;
FFoldActions: TSynFoldActions;
FModes: TSynCustomFoldConfigModes;
FOnChange: TNotifyEvent;
FSupportedModes: TSynCustomFoldConfigModes;
procedure SetFEnabled(const AValue: Boolean);
procedure SetModes(const AValue: TSynCustomFoldConfigModes);
protected
procedure DoOnChange;
public
constructor Create;
procedure Assign(Src: TSynCustomFoldConfig); reintroduce; virtual;
property OnChange: TNotifyEvent read FOnChange write FOnChange;
property SupportedModes: TSynCustomFoldConfigModes
read FSupportedModes write FSupportedModes;
// Actions representing the modes
property FoldActions: TSynFoldActions read FFoldActions;
published
property Enabled: Boolean read FEnabled write SetFEnabled;
property Modes: TSynCustomFoldConfigModes read FModes write SetModes default [fmFold];
end;
{ TSynCustomCodeFoldBlock }
@ -108,27 +146,6 @@ type
TSynCustomHighlighterRanges = class;
TSynFoldAction = (sfaOpen, // At this node a new Fold can start
sfaClose, // At this node a fold ends
sfaMarkup, // This node can be highlighted, by the matching Word-Pair Markup
sfaFold, // Part of a foldable block
sfaInvalid, // Wrong Index
sfaDefaultCollapsed,
sfaOneLineOpen, // Open, but closes on same line; does *not* have sfaOpen
sfaOneLineClose // Open, but closes on same line; does *not* have sfaOpen
);
TSynFoldActions = set of TSynFoldAction;
TSynFoldNodeInfo = record
LineIndex: Integer;
NodeIndex: Integer; // Indicates the position within the list of info nodes (depends on search-Filter
LogXStart, LogXEnd: Integer; // -1 previous line
FoldLvlStart, FoldLvlEnd: Integer;
FoldAction: TSynFoldActions;
FoldType: Pointer;
FoldGroup: Integer;
end;
{ TSynCustomFoldHighlighter }
TSynCustomFoldHighlighter = class(TSynCustomHighlighter)
@ -178,8 +195,9 @@ type
function FoldNestCount(ALineIndex: Integer; AType: Integer = 0): integer; virtual;
function FoldTypeCount: integer; virtual;
function FoldTypeAtNodeIndex(ALineIndex, FoldIndex: Integer;
UseCloseNodes: boolean = false): integer; virtual;
UseCloseNodes: boolean = false): integer; virtual; // TODO: could be deprecated ./ only child-classes
function FoldLineLength(ALineIndex, FoldIndex: Integer): integer; virtual;
function FoldEndLine(ALineIndex, FoldIndex: Integer): integer; virtual; // FoldEndLine, can be more than given by FoldLineLength, since Length my cut off early
// All fold-nodes
property FoldNodeInfo[Line, Index: Integer; Filter: TSynFoldActions]: TSynFoldNodeInfo read GetFoldNodeInfo;
@ -358,8 +376,18 @@ begin
end;
function TSynCustomFoldHighlighter.FoldLineLength(ALineIndex, FoldIndex: Integer): integer;
begin
Result := FoldLineLength(ALineIndex, FoldIndex);
// check if fold last line of block (not mixed "end begin")
if (EndFoldLevel(Result) > MinimumFoldLevel(Result)) then
dec(Result);
// Amount of lines, that will become invisible (excludes the cfCollapsed line)
Result := Result - ALineIndex;
end;
function TSynCustomFoldHighlighter.FoldEndLine(ALineIndex, FoldIndex: Integer): integer;
var
i, lvl, cnt: Integer;
lvl, cnt: Integer;
e, m: Integer;
begin
//atype := FoldTypeAtNodeIndex(ALineIndex, FoldIndex);
@ -367,20 +395,16 @@ begin
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;
Result := ALineIndex + 1;
while (Result < cnt) and (MinimumFoldLevel(Result) >= lvl) do inc(Result);
if (Result = cnt) then
dec(Result);
end;
function TSynCustomFoldHighlighter.GetFoldNodeInfoCount(Line: Integer;
Filter: TSynFoldActions): Integer;
begin
Result := 0;
Result := -1;
end;
function TSynCustomFoldHighlighter.GetFoldConfig(Index: Integer): TSynCustomFoldConfig;
@ -832,15 +856,35 @@ begin
DoOnChange;
end;
procedure TSynCustomFoldConfig.SetModes(const AValue: TSynCustomFoldConfigModes);
begin
if FModes = AValue then exit;
FModes := AValue;
FFoldActions := [];
if AValue <> [] then FFoldActions := FFoldActions + [sfaFold];
if fmFold in AValue then FFoldActions := FFoldActions + [sfaFoldFold];
if fmHide in AValue then FFoldActions := FFoldActions + [sfaFoldHide];
DoOnChange;
end;
procedure TSynCustomFoldConfig.DoOnChange;
begin
if assigned(FOnChange) then
FOnChange(self);
end;
constructor TSynCustomFoldConfig.Create;
begin
Inherited;
FSupportedModes := [fmFold];
Modes := [fmFold];
end;
procedure TSynCustomFoldConfig.Assign(Src: TSynCustomFoldConfig);
begin
Enabled := Src.Enabled;
SupportedModes := Src.SupportedModes;
Modes := Src.Modes;
end;
end.

View File

@ -121,86 +121,64 @@ var
function FindEndNode(StartNode: TSynFoldNodeInfo;
var YIndex, NIndex: Integer): TSynFoldNodeInfo;
function SearchLine(ALineIdx: Integer; var ANodeIdx: Integer): TSynFoldNodeInfo;
begin
repeat
inc(ANodeIdx);
Result := HL.FoldNodeInfo[ALineIdx, ANodeIdx, [sfaMarkup]];
until (sfaInvalid in Result.FoldAction)
or (Result.NestLvlEnd <= StartNode.NestLvlStart);
end;
begin
repeat
inc(NIndex);
Result := HL.FoldNodeInfo[YIndex, NIndex, []];
until (sfaInvalid in Result.FoldAction) or
(Result.FoldLvlEnd <= StartNode.FoldLvlStart);
Result := SearchLine(YIndex, NIndex);
if not (sfaInvalid in Result.FoldAction) then
exit;
inc(YIndex);
while (YIndex < LCnt) and
(HL.MinimumFoldLevel(YIndex) > StartNode.FoldLvlStart) do
while (YIndex < LCnt) and (HL.MinimumFoldLevel(YIndex) > StartNode.NestLvlStart) do
inc(YIndex);
if YIndex = LCnt then
exit;
NIndex := -1;
repeat
inc(NIndex);
Result:= HL.FoldNodeInfo[YIndex, NIndex, []];
until (sfaInvalid in Result.FoldAction) or
(Result.FoldLvlEnd <= StartNode.FoldLvlStart);
if (Result.LogXEnd = 0) then
Result := SearchLine(YIndex, NIndex);
if (Result.LogXEnd = 0) or (sfaLastLineClose in Result.FoldAction) then
Result.FoldAction := [sfaInvalid]; // LastLine closed Node(maybe force-closed?)
end;
function FindStartNode(EndNode: TSynFoldNodeInfo;
var YIndex, NIndex: Integer): TSynFoldNodeInfo;
function SearchLine(ALineIdx: Integer; var ANodeIdx: Integer): TSynFoldNodeInfo;
begin
repeat
dec(ANodeIdx);
Result := HL.FoldNodeInfo[ALineIdx, ANodeIdx, [sfaMarkup]];
until (sfaInvalid in Result.FoldAction)
or (Result.NestLvlStart <= EndNode.NestLvlEnd);
end;
begin
repeat
dec(NIndex);
Result := HL.FoldNodeInfo[YIndex, NIndex, []];
until (sfaInvalid in Result.FoldAction) or
(Result.FoldLvlStart <= EndNode.FoldLvlEnd);
Result := SearchLine(YIndex, NIndex);
if not(sfaInvalid in Result.FoldAction) then
exit;
dec(YIndex);
while (YIndex >= 0) and (HL.MinimumFoldLevel(YIndex) > EndNode.FoldLvlEnd) do
while (YIndex >= 0) and (HL.MinimumFoldLevel(YIndex) > EndNode.NestLvlEnd) do
dec(YIndex);
if YIndex < 0 then
exit;
NIndex := HL.FoldNodeInfoCount[YIndex, []];
repeat
dec(NIndex);
Result:= HL.FoldNodeInfo[YIndex, NIndex, []];
until (sfaInvalid in Result.FoldAction) or
(Result.FoldLvlStart <= EndNode.FoldLvlEnd);
end;
function FindMultiNode(OrigNode: TSynFoldNodeInfo;
var YIndex, NIndex: Integer): TSynFoldNodeInfo;
var
i: LongInt;
begin
i := NIndex;
repeat
dec(NIndex);
Result := HL.FoldNodeInfo[YIndex, NIndex, []];
if (sfaMarkup in Result.FoldAction) and
(Result.LogXStart = OrigNode.LogXStart) and (Result.LogXEnd > 0)
then
exit;
until (sfaInvalid in Result.FoldAction) or (Result.LogXStart <> OrigNode.LogXStart);
NIndex := i;
repeat
inc(NIndex);
Result := HL.FoldNodeInfo[YIndex, NIndex, []];
if (sfaMarkup in Result.FoldAction) and
(Result.LogXStart = OrigNode.LogXStart) and (Result.LogXEnd > 0)
then
exit;
until (sfaInvalid in Result.FoldAction) or (Result.LogXStart <> OrigNode.LogXStart);
Result.FoldAction := [sfaInvalid];
NIndex := HL.FoldNodeInfoCount[YIndex, [sfaMarkup]];
Result := SearchLine(YIndex, NIndex);
if (Result.LogXEnd = 0) or (sfaLastLineClose in Result.FoldAction) then
Result.FoldAction := [sfaInvalid]; // LastLine closed Node(maybe force-closed?)
end;
var
LogCaretXY: TPoint;
i, i2, i3, y, y1, y2: integer;
Node1, Node2, Node3: TSynFoldNodeInfo;
i, i2, y, y2: integer;
Node1, Node2, Node3, TmpNode: TSynFoldNodeInfo;
begin
Word1.Y := -1;
Word2.Y := -1;
@ -209,74 +187,83 @@ begin
(PhysCaret.Y < 1) or (PhysCaret.Y > Lines.Count) or (PhysCaret.X < 1)
then
Exit;
if not (FHighlighter is TSynCustomFoldHighlighter) then
exit;
hl := TSynCustomFoldHighlighter(FHighlighter);
LogCaretXY := Lines.PhysicalToLogicalPos(PhysCaret);
y := LogCaretXY.Y - 1;
LCnt := Lines.Count;
HL.CurrentLines := Lines;
i := 0;
repeat
Node1 := HL.FoldNodeInfo[y, i, []];
inc(i);
until (sfaInvalid in Node1.FoldAction) or
((Node1.LogXEnd >= LogCaretXY.X - 1) and (Node1.LogXEnd > 0));
while not(Node1.FoldAction * [sfaInvalid, sfaMarkup] <> [])
and (Node1.LogXStart <= LogCaretXY.X - 1) do
begin
Node1 := HL.FoldNodeInfo[y, i, []];
inc(i);
end;
if (Node1.LogXStart > LogCaretXY.X - 1) or not(sfaMarkup in Node1.FoldAction) then
exit;
dec(i);
if sfaOpen in Node1.FoldAction then begin
y1 := y;
i := 0;
Node1 := HL.FoldNodeInfo[y, i, [sfaMarkup]];
while not(sfaInvalid in Node1.FoldAction) and (Node1.LogXEnd < LogCaretXY.X-1) do
begin
inc(i);
Node1 := HL.FoldNodeInfo[y, i, [sfaMarkup]];
end;
if (Node1.LogXStart > LogCaretXY.X - 1) or (sfaInvalid in Node1.FoldAction) then
exit;
if Node1.FoldAction * [sfaOpen, sfaOneLineOpen] <> [] then begin
//y1 := y;
Node2 := FindEndNode(Node1, y, i);
if (sfaInvalid in Node2.FoldAction) or not(sfaMarkup in Node2.FoldAction) then
if (sfaInvalid in Node2.FoldAction) then
exit;
y2 := y;
i2 := i;
i3 := i;
Node3 := FindMultiNode(Node2, y, i3);
end else begin
Node2 := Node1;
i3 := i;
Node3 := FindMultiNode(Node2, y, i3);
y2 := y;
i2 := i;
Node1 := FindStartNode(Node2, y, i);
if (sfaInvalid in Node1.FoldAction) or not(sfaMarkup in Node1.FoldAction) then
Node1 := FindStartNode(Node2, y, i); // skip = endnode => do not skup anything
if (sfaInvalid in Node1.FoldAction) then
exit;
y1 := y;
end;
Node3.FoldAction := [sfaInvalid];
i := i2;
y := y2;
if not(sfaInvalid in Node3.FoldAction) then
Node3 := FindStartNode(Node3, y, i);
TmpNode := HL.FoldNodeInfo[y2, i2 - 1, [sfaMarkup]];
if (not (sfaInvalid in TmpNode.FoldAction)) and
(TmpNode.LogXStart = Node2.LogXStart) and (TmpNode.LogXEnd = Node2.LogXEnd)
then begin
// tripple node => 3rd start after current start
TmpNode := FindStartNode(TmpNode, y2, i2);
if (not (sfaInvalid in TmpNode.FoldAction)) then begin
Node3 := Node2;
Node2 := TmpNode;
end;
end
else begin
y2 := y;
i2 := i;
TmpNode := HL.FoldNodeInfo[y2, i2 + 1, [sfaMarkup]];
if (not (sfaInvalid in TmpNode.FoldAction)) and
(TmpNode.LogXStart = Node2.LogXStart) and (TmpNode.LogXEnd = Node2.LogXEnd)
then begin
// tripple node => 3rd start before current start
TmpNode := FindStartNode(TmpNode, y2, i2);
if (not (sfaInvalid in TmpNode.FoldAction)) then begin
Node3 := Node2;
Node2 := Node1;
Node1 := TmpNode;
end;
end
end;
Word1.Y := y1 + 1;
Word1.Y := Node1.LineIndex + 1;
Word1.X := Node1.LogXStart + 1;
Word1.X2 := Node1.LogXEnd + 1;
Word2.Y := y2 + 1;
Word2.Y := Node2.LineIndex + 1;
Word2.X := Node2.LogXStart + 1;
Word2.X2 := Node2.LogXEnd + 1;
if (sfaMarkup in Node3.FoldAction) and not(sfaInvalid in Node3.FoldAction) then
if not(sfaInvalid in Node3.FoldAction) then
begin
Word3 := Word2;
if i3 > i2 then begin
Word2 := Word1;
Word1.Y := y + 1;
Word1.X := Node3.LogXStart + 1;
Word1.X2 := Node3.LogXEnd + 1;
end else begin
Word2.Y := y + 1;
Word2.X := Node3.LogXStart + 1;
Word2.X2 := Node3.LogXEnd + 1;
end;
Word3.Y := Node3.LineIndex + 1;
Word3.X := Node3.LogXStart + 1;
Word3.X2 := Node3.LogXEnd + 1;
end;
if Word1.Y > 0 then begin

View File

@ -44,8 +44,12 @@ type
FMouseActionsExpanded: TSynEditMouseActions;
FPopUp: TPopupMenu;
FMenuInf: Array of TFoldViewNodeInfo;
FIsFoldHidePreviousLine: Boolean;
procedure SetMouseActionsCollapsed(const AValue: TSynEditMouseActions);
procedure SetMouseActionsExpanded(const AValue: TSynEditMouseActions);
function FoldTypeForLine(AScreenLine: Integer): TSynEditFoldLineCapability;
function IsFoldHidePreviousLine(AScreenLine: Integer): Boolean;
function IsSingleLineHide(AScreenLine: Integer): Boolean;
protected
procedure DoChange(Sender: TObject); override;
procedure PopClicked(Sender: TObject);
@ -91,6 +95,62 @@ begin
FMouseActionsExpanded.Assign(AValue);
end;
function TSynGutterCodeFolding.FoldTypeForLine(AScreenLine: Integer): TSynEditFoldLineCapability;
var
tmp, tmp2: TSynEditFoldLineCapabilities;
begin
tmp := FFoldView.FoldType[AScreenLine];
tmp2 := FFoldView.FoldType[AScreenLine-1];
FIsFoldHidePreviousLine := False;
if (AScreenLine = 0) and (FFoldView.TextIndexToViewPos(FFoldView.TextIndex[0]) = 1) and
(cfCollapsedHide in tmp2)
then begin
Result := cfCollapsedHide;
FIsFoldHidePreviousLine := True;
end
//if tmp * [cfHideStart, cfFoldStart, cfCollapsedFold] = [cfHideStart, cfFoldStart, cfCollapsedFold]
// then Result := cfHideStart
else if cfCollapsedFold in tmp then Result := cfCollapsedFold
else if cfCollapsedHide in tmp then Result := cfCollapsedHide
else if cfFoldStart in tmp then Result := cfFoldStart
else if cfHideStart in tmp then Result := cfHideStart
else if cfFoldEnd in tmp then Result := cfFoldEnd
else if cfFoldBody in tmp then Result := cfFoldBody
else
Result := cfNone;
if Result in [cfFoldBody, cfFoldEnd] then begin
tmp := FFoldView.FoldType[AScreenLine - 1];
if tmp * [cfHideStart, cfFoldStart, cfCollapsedFold, cfCollapsedHide]
= [cfHideStart, cfFoldStart]
then begin
FIsFoldHidePreviousLine := True;
Result := cfHideStart // hide for previous line
end;
end;
end;
function TSynGutterCodeFolding.IsFoldHidePreviousLine(AScreenLine: Integer): Boolean;
begin
FoldTypeForLine(AScreenLine);
Result := FIsFoldHidePreviousLine;
end;
function TSynGutterCodeFolding.IsSingleLineHide(AScreenLine: Integer): Boolean;
var
tmp: TSynEditFoldLineCapabilities;
begin
Result := False;
tmp := FFoldView.FoldType[AScreenLine];
if tmp * [cfHideStart, cfFoldStart, cfCollapsedFold] =
[cfHideStart, cfFoldStart, cfCollapsedFold]
then
Result := True;
if cfSingleLineHide in tmp then
Result := True;
end;
procedure TSynGutterCodeFolding.DoChange(Sender: TObject);
begin
if AutoSize then
@ -152,14 +212,18 @@ end;
function TSynGutterCodeFolding.MaybeHandleMouseAction(var AnInfo: TSynEditMouseActionInfo;
HandleActionProc: TSynEditMouseActionHandler): Boolean;
var
tmp: TSynEditFoldLineCapability;
begin
Result := False;
case FFoldView.FoldType[FFoldView.TextIndexToScreenLine(AnInfo.NewCaret.LinePos-1)] of
cfCollapsed :
tmp := FoldTypeForLine(FFoldView.TextIndexToScreenLine(AnInfo.NewCaret.LinePos-1));
case tmp of
cfCollapsedFold, cfCollapsedHide:
Result := HandleActionProc(MouseActionsCollapsed, AnInfo);
cfExpanded :
cfFoldStart, cfHideStart:
Result := HandleActionProc(MouseActionsExpanded, AnInfo);
end;
if not Result then
Result := HandleActionProc(MouseActions, AnInfo);
end;
@ -167,17 +231,30 @@ end;
function TSynGutterCodeFolding.DoHandleMouseAction(AnAction: TSynEditMouseAction;
var AnInfo: TSynEditMouseActionInfo): Boolean;
var
c, i, line: Integer;
c, i, line, ScrLine: Integer;
inf: TFoldViewNodeInfo;
m: TMenuItem;
s, s2: String;
ACommand: Word;
KeepVisible: Integer;
begin
Result := False;
if AnAction = nil then exit;
ACommand := AnAction.Command;
if (ACommand = emcNone) then exit;
line := AnInfo.NewCaret.LinePos;
ScrLine := FFoldView.TextIndexToScreenLine(Line-1);
KeepVisible := 1;
if FoldTypeForLine(ScrLine) = cfHideStart then KeepVisible := 0;
if (FoldTypeForLine(ScrLine) = cfCollapsedHide) then begin
if IsFoldHidePreviousLine(ScrLine) then
line := FFoldView.TextIndex[ScrLine-1] + 1;
inc(line);
KeepVisible := 0;
end
else
if IsFoldHidePreviousLine(ScrLine) then dec(line);
Result := True;
case ACommand of
@ -185,26 +262,32 @@ begin
begin
case AnAction.Option of
emcoCodeFoldCollapsOne:
FFoldView.FoldAtTextIndex(Line-1, -1, 1, True);
begin
FFoldView.FoldAtTextIndex(Line-1, -1, 1, True, KeepVisible);
end;
emcoCodeFoldCollapsAll:
FFoldView.FoldAtTextIndex(Line-1, -1, 0);
begin
FFoldView.FoldAtTextIndex(Line-1, -1, 0, False, KeepVisible);
end;
emcoCodeFoldCollapsAtCaret:
// Keyword at mouseclick/caret position
begin
i := FFoldView.LogicalPosToNodeIndex(Line-1, AnInfo.NewCaret.BytePos, False);
if i >= 0 then
FFoldView.FoldAtTextIndex(Line-1, i, 1, False)
FFoldView.FoldAtTextIndex(Line-1, i, 1, False, KeepVisible)
else
Result := False;
end;
emcoCodeFoldCollapsPreCaret:
// mouseclick/caret position anywhere inside the fold
begin
i := FFoldView.LogicalPosToNodeIndex(Line-1, AnInfo.NewCaret.BytePos, True);
if i >= 0 then
FFoldView.FoldAtTextIndex(Line-1, i, 1, False)
FFoldView.FoldAtTextIndex(Line-1, i, 1, False, KeepVisible)
else begin
i := FFoldView.ExpandedLineForBlockAtLine(Line);
if i > 0 then
FFoldView.FoldAtTextIndex(i-1, -1, 1, True);
FFoldView.FoldAtTextIndex(i-1, -1, 1, True, KeepVisible);
end;
end;
end;
@ -213,9 +296,9 @@ begin
begin
case AnAction.Option of
emcoCodeFoldExpandOne:
FFoldView.UnFoldAtTextIndex(line-1, 0, 1, True);
FFoldView.UnFoldAtTextIndex(line-1, 0, 1, True, KeepVisible);
emcoCodeFoldExpandAll:
FFoldView.UnFoldAtTextIndex(line-1);
FFoldView.UnFoldAtTextIndex(line-1, -1, 0, False, KeepVisible);
end;
end;
emcCodeFoldContextMenu:
@ -264,18 +347,27 @@ var
iLine: integer;
rcLine: TRect;
rcCodeFold: TRect;
tmp: TSynEditCodeFoldType;
tmp: TSynEditFoldLineCapability;
LineHeight, LineOffset, BoxSize: Integer;
procedure DrawNodeBox(rcCodeFold: TRect; Collapsed: boolean);
procedure DrawNodeBox(rcCodeFold: TRect; NodeType: TSynEditFoldLineCapability);
var
rcNode: TRect;
ptCenter : TPoint;
isPrevLine: Boolean;
Points: Array [0..3] of TPoint;
begin
isPrevLine := IsFoldHidePreviousLine(iLine);
LineOffset := 0;
//center of the draw area
ptCenter.X := (rcCodeFold.Left + rcCodeFold.Right) div 2;
ptCenter.Y := (rcCodeFold.Top + rcCodeFold.Bottom) div 2;
// If belongs to line above, draw at very top
if isPrevLine then
ptCenter.Y := rcCodeFold.Top + (BoxSize div 2) - 1;
//area of drawbox
rcNode.Left := ptCenter.X - (BoxSize div 2) + 1;
rcNode.Right := ptCenter.X + (BoxSize div 2);
@ -284,25 +376,79 @@ var
Canvas.Brush.Style := bsClear;
//draw Paragraph end
if isPrevLine and (cfFoldEnd in FFoldView.FoldType[iLine]) and
(rcCodeFold.Bottom-1 > rcNode.Bottom)
then begin
Canvas.MoveTo(ptCenter.X, rcNode.Bottom);
Canvas.LineTo(ptCenter.X, rcCodeFold.Bottom-1);
Canvas.LineTo(rcCodeFold.Right, rcCodeFold.Bottom-1);
LineOffset := min(2, (rcCodeFold.Top + rcCodeFold.Bottom) div 2);
end
else
//draw bottom handle to paragraph line
Canvas.MoveTo(ptCenter.X, rcNode.Bottom);
Canvas.LineTo(ptCenter.X, rcCodeFold.Bottom);
if (cfFoldBody in FFoldView.FoldType[iLine + 1]) and
(not IsSingleLineHide(iLine))
then begin
Canvas.MoveTo(ptCenter.X, rcNode.Bottom);
Canvas.LineTo(ptCenter.X, rcCodeFold.Bottom);
end;
if Collapsed and (MarkupInfo.FrameColor <> clNone) then
if (NodeType in [cfCollapsedFold, cfCollapsedHide]) and
(MarkupInfo.FrameColor <> clNone)
then
Canvas.Pen.Color := MarkupInfo.FrameColor;
Canvas.Rectangle(rcNode);
//draw unfolded sign in node box
Canvas.MoveTo(ptCenter.X - 2, ptCenter.Y);
Canvas.LineTo(ptCenter.X + 3, ptCenter.Y);
//draw folded sign
if Collapsed then
begin
Canvas.MoveTo(ptCenter.X, ptCenter.Y - 2);
Canvas.LineTo(ptCenter.X, ptCenter.Y + 3);
case NodeType of
cfFoldStart:
begin
// [-]
Canvas.MoveTo(ptCenter.X - 2, ptCenter.Y);
Canvas.LineTo(ptCenter.X + 3, ptCenter.Y);
end;
cfHideStart:
begin
// [.]
Canvas.MoveTo(ptCenter.X, ptCenter.Y);
Canvas.LineTo(ptCenter.X + 1, ptCenter.Y);
end;
cfCollapsedFold:
begin
// [+]
Canvas.MoveTo(ptCenter.X - 2, ptCenter.Y);
Canvas.LineTo(ptCenter.X + 3, ptCenter.Y);
Canvas.MoveTo(ptCenter.X, ptCenter.Y - 2);
Canvas.LineTo(ptCenter.X, ptCenter.Y + 3);
end;
cfCollapsedHide:
begin
if isPrevLine then begin
// [v]
Points[0].X := ptCenter.X;
Points[0].y := ptCenter.Y - 2;
Points[1].X := ptCenter.X - 2;
Points[1].y := ptCenter.Y;
Points[2].X := ptCenter.X + 2;
Points[2].y := ptCenter.Y;
Points[3].X := ptCenter.X;
Points[3].y := ptCenter.Y - 2;
end else begin
// [v]
Points[0].X := ptCenter.X;
Points[0].y := ptCenter.Y + 2;
Points[1].X := ptCenter.X - 2;
Points[1].y := ptCenter.Y;
Points[2].X := ptCenter.X + 2;
Points[2].y := ptCenter.Y;
Points[3].X := ptCenter.X;
Points[3].y := ptCenter.Y + 2;
end;
Canvas.Polygon(Points);
end;
end;
LineOffset := 0;
Canvas.Pen.Color := MarkupInfo.Foreground;
Canvas.Brush.Style := bsSolid;
end;
@ -336,16 +482,15 @@ begin
if not Visible then exit;
LineHeight := TSynEdit(SynEdit).LineHeight;
LineOffset := 0;
if (FirstLine > 0) and (FFoldView.FoldType[FirstLine-1] = cfEnd) then
if (FirstLine > 0) and
(FFoldView.FoldType[FirstLine-1] - [cfFoldBody] = [cfFoldEnd]) then
LineOffset := 2;
BoxSize := Min(Width, LineHeight - cNodeOffset*2);
if MarkupInfo.Background <> clNone then
begin
Canvas.Brush.Color := MarkupInfo.Background;
{$IFDEF SYN_LAZARUS}
LCLIntf.SetBkColor(Canvas.Handle, Canvas.Brush.Color);
{$ENDIF}
Canvas.FillRect(AClip);
end;
@ -366,14 +511,16 @@ begin
rcCodeFold.Top := rcLine.Top;
rcCodeFold.Bottom := rcLine.Bottom;
tmp := FFoldView.FoldType[iLine];
tmp := FoldTypeForLine(iLine);
case tmp of
cfCollapsed: DrawNodeBox(rcCodeFold, True);
cfExpanded: DrawNodeBox(rcCodeFold, False);
cfContinue: DrawParagraphContinue(rcCodeFold);
cfEnd: DrawParagraphEnd(rcCodeFold);
else LineOffset := 0;
cfFoldStart, cfHideStart, cfCollapsedFold, cfCollapsedHide:
DrawNodeBox(rcCodeFold, tmp);
cfFoldBody:
DrawParagraphContinue(rcCodeFold);
cfFoldEnd:
DrawParagraphEnd(rcCodeFold);
else
LineOffset := 0;
end;
end;
end;

View File

@ -70,6 +70,7 @@ type
// rsAnsi, rsBor, rsDirective are exclusive to each other
rsAnsi, // *) comment
rsBor, // { comment
rsSlash, // //
{$IFDEF SYN_LAZARUS}
rsDirective,
{$ENDIF}
@ -91,7 +92,7 @@ type
type
{$IFDEF SYN_LAZARUS}
TPascalCodeFoldBlockType = (
TPascalCodeFoldBlockType = ( // Do *not* change the order
cfbtBeginEnd, // Nested
cfbtTopBeginEnd, // Begin of Procedure
cfbtNestedComment,
@ -407,6 +408,7 @@ type
procedure EqualSignProc;
procedure SemicolonProc; //mh 2000-10-08
procedure SlashProc;
procedure SlashContinueProc;
procedure SpaceProc;
procedure StringProc;
procedure SymbolProc;
@ -441,8 +443,10 @@ type
function TopPascalCodeFoldBlockType
(DownIndex: Integer = 0): TPascalCodeFoldBlockType;
public
function MinimumPasFoldLevel(Index: Integer; AType: Integer = 1): integer;
function EndPasFoldLevel(Index: Integer; AType: Integer = 1): integer;
protected
function LastLinePasFoldLevelFix(Index: Integer; AType: Integer = 1): integer;
function LastLineFoldLevelFix(Index: Integer): integer;
@ -453,6 +457,7 @@ type
function GetFoldConfigInstance(Index: Integer): TSynCustomFoldConfig; override;
function GetFoldConfigCount: Integer; override;
function GetFoldConfigInternalCount: Integer; override;
procedure DoFoldConfigChanged(Sender: TObject); override;
public
{$IFNDEF SYN_CPPB_1} class {$ENDIF}
function GetCapabilities: TSynHighlighterCapabilities; override;
@ -493,8 +498,9 @@ type
function FoldTypeAtNodeIndex(ALineIndex, FoldIndex: Integer;
UseCloseNodes: boolean = false): integer; override;
function FoldLineLength(ALineIndex, FoldIndex: Integer): integer; override;
function FoldEndLine(ALineIndex, FoldIndex: Integer): integer; override;
// Pascal coe only // TODO: make private
// Pascal code only // TODO: make private
function MinimumFoldLevel(Index: Integer): integer; override;
function EndFoldLevel(Index: Integer): integer; override;
published
@ -939,13 +945,13 @@ begin
EndPascalCodeFoldBlock;
if TopPascalCodeFoldBlockType in [cfbtProcedure] then
EndPascalCodeFoldBlock;
if TopPascalCodeFoldBlockType = cfbtProgram then
EndPascalCodeFoldBlock;
end else if tfb in [cfbtCase] then begin
EndPascalCodeFoldBlock;
fRange := fRange - [rsAtCaseLabel];
end else if tfb in [cfbtBeginEnd] then begin
EndPascalCodeFoldBlock;
if TopPascalCodeFoldBlockType = cfbtProgram then
EndPascalCodeFoldBlock;
end else if tfb = cfbtUnitSection then begin
EndPascalCodeFoldBlockLastLine;
if TopPascalCodeFoldBlockType = cfbtUnit then // "Unit".."end."
@ -2317,6 +2323,7 @@ begin
DirectiveProc;
end else begin
// curly bracket open -> borland comment
fStringLen := 1; // length of "{"
inc(Run);
fRange := fRange + [rsBor];
if (Run < fLineLen) and (fLine[Run] = '%') then begin
@ -2333,11 +2340,17 @@ begin
end
else if KeyComp('endregion') then
EndCustomCodeFoldBlock(cfbtRegion)
else
else begin
dec(Run, 2);
StartPascalCodeFoldBlock(cfbtBorCommand);
inc(Run);
end;
end
else
else begin
dec(Run);
StartPascalCodeFoldBlock(cfbtBorCommand);
inc(Run);
end;
BorProc;
end;
end;
@ -2413,6 +2426,11 @@ end;
procedure TSynPasSyn.NullProc;
begin
if (Run = 0) and (rsSlash in fRange) then begin
fRange := fRange - [rsSlash];
if TopPascalCodeFoldBlockType = cfbtSlashComment then
EndPascalCodeFoldBlockLastLine;
end;
fTokenID := tkNull;
{$IFDEF SYN_LAZARUS}
if Run<fLineLen then inc(Run);
@ -2510,11 +2528,13 @@ begin
case fLine[Run] of
'*':
begin
Inc(Run);
// We would not be here, if we were in a comment or directive already
fRange := fRange + [rsAnsi];
fTokenID := tkComment;
fStringLen := 2; // length of "(*"
Dec(Run);
StartPascalCodeFoldBlock(cfbtAnsiComment);
Inc(Run, 2);
if not (fLine[Run] in [#0, #10, #13]) then begin
AnsiProc;
end;
@ -2581,16 +2601,48 @@ end;
procedure TSynPasSyn.SlashProc;
begin
Inc(Run);
if fLine[Run] = '/' then begin
if fLine[Run+1] = '/' then begin
fTokenID := tkComment;
if FAtLineStart then
include(fRange, rsLineIsAllComment);
repeat
if FAtLineStart then begin
fRange := fRange + [rsSlash, rsLineIsAllComment];
fStringLen := 2; // length of "//"
if not(TopPascalCodeFoldBlockType = cfbtSlashComment) then
StartPascalCodeFoldBlock(cfbtSlashComment);
end;
inc(Run, 2);
while not(fLine[Run] in [#0, #10, #13]) do
Inc(Run);
until fLine[Run] in [#0, #10, #13];
end else
end else begin
Inc(Run);
fTokenID := tkSymbol;
end;
end;
procedure TSynPasSyn.SlashContinueProc;
begin
if (fLine[Run] = '/') and (fLine[Run + 1] = '/') then begin
// Continue fold block
fTokenID := tkComment;
while not(fLine[Run] in [#0, #10, #13]) do
Inc(Run);
exit;
end;
fTokenID := tkUnknown;
if IsSpaceChar[FLine[Run]] then begin
fTokenID := tkSpace;
inc(Run);
while IsSpaceChar[FLine[Run]] do inc(Run);
end;
if not((fLine[Run] = '/') and (fLine[Run + 1] = '/')) then begin
fRange := fRange - [rsSlash];
if TopPascalCodeFoldBlockType = cfbtSlashComment then
EndPascalCodeFoldBlockLastLine;
end;
if FTokenID = tkUnknown then
Next;
end;
procedure TSynPasSyn.SpaceProc;
@ -2653,7 +2705,7 @@ begin
fTokenPos := Run;
FTokenIsCaseLabel := False;
if Run>=fLineLen then begin
fTokenID := tkNull;
NullProc;
exit;
end;
case fLine[Run] of
@ -2667,6 +2719,8 @@ begin
BorProc
else if rsDirective in fRange then
DirectiveProc
else if rsSlash in fRange then
SlashContinueProc
else begin
if rsAtEqual in fRange then
fRange := fRange + [rsAfterEqual] - [rsAtEqual]
@ -2674,7 +2728,9 @@ begin
if rsAtClass in fRange then
fRange := fRange + [rsAfterClass] - [rsAtClass];
IsAtCaseLabel := rsAtCaseLabel in fRange;
fProcTable[fLine[Run]];
if (IsAtCaseLabel) and (rsAtCaseLabel in fRange) then begin
FTokenIsCaseLabel := True;
if (FTokenID = tkKey) then
@ -2690,7 +2746,7 @@ begin
fRange := fRange - [rsAtClosingBracket];
end
end;
if not(FTokenID in [tkSpace, tkComment]) then
if FAtLineStart and not(FTokenID in [tkSpace, tkComment]) then
FAtLineStart := False;
//DebugLn(['TSynPasSyn.Next Run=',Run,' fTokenPos=',fTokenPos,' fLineStr=',fLineStr,' Token=',GetToken]);
end;
@ -2882,6 +2938,8 @@ begin
Result := Result + inf.EndLevelRegion - inf.MinLevelRegion;
if (AType = 0) or (AType = 3) then
Result := Result + inf.EndLevelIfDef - inf.MinLevelIfDef;
if Result < 0 then
Result := 0;
end;
function TSynPasSyn.FoldCloseCount(ALineIndex: Integer; AType: Integer = 0): integer;
@ -2941,28 +2999,62 @@ end;
function TSynPasSyn.FoldLineLength(ALineIndex, FoldIndex: Integer): integer;
var
i, lvl, cnt, atype : Integer;
e, m: Integer;
atype : Integer;
node: TSynFoldNodeInfo;
begin
atype := FoldTypeAtNodeIndex(ALineIndex, FoldIndex);
node := GetFoldNodeInfo(ALineIndex, FoldIndex, [sfaOpen, sfaFold]);
if sfaInvalid in node.FoldAction then exit(-1);
if sfaOneLineOpen in node.FoldAction then exit(0);
case TPascalCodeFoldBlockType(PtrUInt(node.FoldType)) of
cfbtRegion:
atype := 2;
cfbtIfDef:
atype := 3;
else
atype := 1;
end;
Result := FoldEndLine(ALineIndex, FoldIndex);
// check if fold last line of block (not mixed "end begin")
if (EndPasFoldLevel(Result, atype) > MinimumPasFoldLevel(Result, atype)) then
dec(Result);
// Amount of lines, that will become invisible (excludes the cfCollapsed line)
Result := Result - ALineIndex;
end;
function TSynPasSyn.FoldEndLine(ALineIndex, FoldIndex: Integer): integer;
var
lvl, cnt, atype : Integer;
e, m: Integer;
node: TSynFoldNodeInfo;
begin
node := GetFoldNodeInfo(ALineIndex, FoldIndex, [sfaOpen, sfaFold]);
if sfaInvalid in node.FoldAction then exit(-1);
if sfaOneLineOpen in node.FoldAction then exit(ALineIndex);
case TPascalCodeFoldBlockType(PtrUInt(node.FoldType)) of
cfbtRegion:
atype := 2;
cfbtIfDef:
atype := 3;
else
atype := 1;
end;
cnt := CurrentLines.Count;
e := EndPasFoldLevel(ALineIndex, atype);
m := MinimumPasFoldLevel(ALineIndex, atype);
lvl := Min(m+1+FoldIndex, e);
i := ALineIndex + 1;
while (i < cnt) and (MinimumPasFoldLevel(i, atype) >= lvl) do inc(i);
lvl := node.FoldLvlEnd;
Result := ALineIndex + 1;
while (Result < cnt) and (MinimumPasFoldLevel(Result, atype) >= lvl) do inc(Result);
// check if fold last line of block (not mixed "end begin")
// and not lastlinefix
if (i = cnt) or (EndPasFoldLevel(i, atype) > MinimumPasFoldLevel(i, atype)) then
dec(i);
// Amount of lines, that will become invisible (excludes the cfCollapsed line)
Result := i - ALineIndex;
if (Result = cnt) then
dec(Result);
end;
function TSynPasSyn.MinimumPasFoldLevel(Index: Integer; AType: Integer = 1): integer;
var
r: TSynPasSynRange;
i1, i2: Integer;
begin
case AType of
2:
@ -2977,24 +3069,8 @@ begin
exit(0);
r := TSynPasSynRange(CurrentRanges[Index]);
if (r <> nil) and (Pointer(r) <> NullRange) then begin
i1 := 0;
i2 := 0;
// Increase result for multiline "//" comments
if FFoldConfig[ord(cfbtSlashComment)].Enabled and
(rsLineIsAllComment in TRangeStates(Integer(PtrUInt(r.RangeType)))) and
(Index + 1 < CurrentLines.Count)
then begin
if rsLineIsAllComment in
TRangeStates(Integer(PtrUInt(TSynPasSynRange(CurrentRanges[Index - 1]).RangeType)))
then
i1 := 1;
if rsLineIsAllComment in
TRangeStates(Integer(PtrUInt(TSynPasSynRange(CurrentRanges[Index + 1]).RangeType)))
then
i2 := 1;
end;
Result := Min(r.PasFoldEndLevel + LastLinePasFoldLevelFix(Index + 1) + i2,
r.PasFoldMinLevel + i1)
Result := Min(r.PasFoldEndLevel + LastLinePasFoldLevelFix(Index + 1),
r.PasFoldMinLevel)
end else
Result := 0;
end;
@ -3005,6 +3081,8 @@ function TSynPasSyn.EndPasFoldLevel(Index: Integer; AType: Integer = 1): integer
var
r: TSynPasSynRange;
begin
if (Index < 0) or (Index >= CurrentLines.Count - 1) then
exit(0);
case AType of
2:
Result := TSynHighlighterPasRangeList(CurrentRanges).
@ -3014,24 +3092,10 @@ begin
PasRangeInfo[Index].EndLevelIfDef;
else
begin
if (Index < 0) or (Index >= CurrentLines.Count) then
exit(0);
r := TSynPasSynRange(CurrentRanges[Index]);
if (r <> nil) and (Pointer(r) <> NullRange) then begin
Result := r.PasFoldEndLevel + LastLinePasFoldLevelFix(Index + 1);
// Increase result for multiline "//" comments
if FFoldConfig[ord(cfbtSlashComment)].Enabled and
(rsLineIsAllComment in TRangeStates(Integer(PtrUInt(r.RangeType)))) and
(Index + 1 < CurrentLines.Count) and (Index > 0)
// and not TopPascalCodeFoldBlockType() in [cfbtAnsiComment, cfbtBorCommand]
then begin
r := TSynPasSynRange(CurrentRanges[Index + 1]);
if (r <> nil) and
(rsLineIsAllComment in TRangeStates(Integer(PtrUInt(r.RangeType))))
then
inc(Result);
end;
end else
if (r <> nil) and (Pointer(r) <> NullRange) then
Result := r.PasFoldEndLevel + LastLinePasFoldLevelFix(Index + 1)
else
Result := 0;
end;
end;
@ -3115,21 +3179,27 @@ begin
begin
node.FoldGroup := 2;
Node.FoldLvlStart := FSynPasRangeInfo.EndLevelRegion;
Node.NestLvlStart := FSynPasRangeInfo.EndLevelRegion;
OneLine := (EndOffs < 0) and (Node.FoldLvlStart > FSynPasRangeInfo.MinLevelRegion);
end;
cfbtIfDef:
begin
node.FoldGroup := 3;
Node.FoldLvlStart := FSynPasRangeInfo.EndLevelIfDef;
Node.NestLvlStart := FSynPasRangeInfo.EndLevelIfDef;
OneLine := (EndOffs < 0) and (Node.FoldLvlStart > FSynPasRangeInfo.MinLevelIfDef);
end;
else
begin
node.FoldGroup := 1;
Node.FoldLvlStart := CurrentCodeFoldBlockLevel;
OneLine := (EndOffs < 0) and (Node.FoldLvlStart > MinimumCodeFoldBlockLevel);
Node.FoldLvlStart := PasCodeFoldRange.PasFoldEndLevel;
Node.NestLvlStart := CurrentCodeFoldBlockLevel;
OneLine := (EndOffs < 0) and (Node.FoldLvlStart > PasCodeFoldRange.PasFoldMinLevel); // MinimumCodeFoldBlockLevel);
end;
end;
Node.NestLvlEnd := Node.NestLvlStart + EndOffs;
if not (sfaFold in aActions) then
EndOffs := 0;
Node.FoldLvlEnd := Node.FoldLvlStart + EndOffs;
if OneLine then begin // find opening node
i := FNodeInfoCount - 1;
@ -3141,9 +3211,17 @@ begin
) do
dec(i);
if i >= 0 then begin
FNodeInfoList[i].FoldAction := FNodeInfoList[i].FoldAction
- [sfaOpen, sfaFold] + [sfaOneLineOpen];
Node.FoldAction := Node.FoldAction + [sfaOneLineClose] - [sfaClose, sfaFold];
FNodeInfoList[i].FoldAction := FNodeInfoList[i].FoldAction + [sfaOneLineOpen];
Node.FoldAction := Node.FoldAction + [sfaOneLineClose];
if (sfaFoldHide in FNodeInfoList[i].FoldAction) then begin
// one liner: hide-able / not fold-able
FNodeInfoList[i].FoldAction := FNodeInfoList[i].FoldAction - [sfaFoldFold];
Node.FoldAction := Node.FoldAction - [sfaFoldFold];
end else begin
// one liner: nether hide-able nore fold-able
FNodeInfoList[i].FoldAction := FNodeInfoList[i].FoldAction - [sfaOpen, sfaFold];
Node.FoldAction := Node.FoldAction - [sfaClose, sfaFold];
end;
end;
end;
if ABlockType in PascalWordTrippletRanges then
@ -3151,11 +3229,16 @@ begin
end;
procedure TSynPasSyn.StartCustomCodeFoldBlock(ABlockType: TPascalCodeFoldBlockType);
var
act: TSynFoldActions;
begin
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]);
act := FFoldConfig[ord(ABlockType)].FoldActions;
if not FAtLineStart then
act := act - [sfaFoldHide];
InitNode(FNodeInfoList[FNodeInfoCount], +1, ABlockType, [sfaOpen] + act);
inc(FNodeInfoCount);
end;
case ABlockType of
@ -3171,7 +3254,8 @@ begin
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]);
InitNode(FNodeInfoList[FNodeInfoCount], -1, ABlockType,
[sfaClose, sfaFold]); // + FFoldConfig[ord(ABlockType)].FoldActions);
inc(FNodeInfoCount);
end;
case ABlockType of
@ -3206,7 +3290,9 @@ begin
GrowNodeInfoList;
act := [sfaOpen];
if FoldBlock then
include(act, sfaFold);
act := act + FFoldConfig[ord(ABlockType)].FoldActions;
if not FAtLineStart then
act := act - [sfaFoldHide];
InitNode(FNodeInfoList[FNodeInfoCount], +1, ABlockType, act);
inc(FNodeInfoCount);
end;
@ -3220,13 +3306,15 @@ procedure TSynPasSyn.EndPascalCodeFoldBlock(NoMarkup: Boolean = False);
var
DecreaseLevel: Boolean;
act: TSynFoldActions;
BlockType: Pointer;
begin
DecreaseLevel := TopCodeFoldBlockType < CountPascalCodeFoldBlockOffset;
BlockType := TopCodeFoldBlockType;
DecreaseLevel := BlockType < CountPascalCodeFoldBlockOffset;
if FCatchNodeInfo then begin // exclude subblocks, because they do not increase the foldlevel yet
GrowNodeInfoList;
act := [sfaClose];
if DecreaseLevel then
include(act, sfaFold);
act := act + [sfaFold]; //FFoldConfig[PtrUInt(BlockType)].FoldActions;
InitNode(FNodeInfoList[FNodeInfoCount], -1, TopPascalCodeFoldBlockType, act);
if NoMarkup then
exclude(FNodeInfoList[FNodeInfoCount].FoldAction, sfaMarkup);
@ -3460,6 +3548,12 @@ begin
cfbtProcedure, cfbtUses, cfbtLocalVarType, cfbtClass,
cfbtClassSection, cfbtRecord, cfbtRepeat, cfbtCase,
cfbtAsm, cfbtRegion];
if TPascalCodeFoldBlockType(Index) in
[cfbtRegion, cfbtNestedComment, cfbtAnsiComment, cfbtBorCommand, cfbtSlashComment]
then
Result.SupportedModes := [fmFold, fmHide];
if TPascalCodeFoldBlockType(Index) in [cfbtSlashComment] then
Result.Modes := [fmFold, fmHide];
end;
function TSynPasSyn.CreateRangeList(ALines: TSynEditStringsBase): TSynHighlighterRangeList;
@ -3496,6 +3590,12 @@ begin
+ 1;
end;
procedure TSynPasSyn.DoFoldConfigChanged(Sender: TObject);
begin
FNodeInfoLine := -1;
inherited DoFoldConfigChanged(Sender);
end;
function TSynPasSyn.GetDividerDrawConfig(Index: Integer): TSynDividerDrawConfig;
begin
Result := FDividerDrawConfig[TSynPasDividerDrawLocation(Index)];
@ -3518,11 +3618,27 @@ begin
StartAtLineIndex(Line);
fStringLen := 0;
NextToEol;
fStringLen := 0;
i := LastLineFoldLevelFix(Line+1);
while i < 0 do begin
EndPascalCodeFoldBlock;
inc(i);
end;
if Line = CurrentLines.Count - 1 then begin
// last line, close all folds
// Run (for LogXStart) is at line-end
i := FNodeInfoCount;
while TopPascalCodeFoldBlockType <> cfbtNone do
EndPascalCodeFoldBlock(True);
while FSynPasRangeInfo.EndLevelIfDef > 0 do
EndCustomCodeFoldBlock(cfbtIfDef);
while FSynPasRangeInfo.EndLevelRegion > 0 do
EndCustomCodeFoldBlock(cfbtRegion);
while i < FNodeInfoCount do begin
FNodeInfoList[i].FoldAction := FNodeInfoList[i].FoldAction + [sfaLastLineClose];
inc(i);
end;
end;
FCatchNodeInfo := False;
FNodeInfoLine := Line;
end;
@ -3534,6 +3650,7 @@ begin
Result := FNodeInfoList[Index]
else
begin
Result.FoldAction := [sfaInvalid];
j := Index;
for i := 0 to FNodeInfoCount - 1 do
if FNodeInfoList[i].FoldAction * Filter = Filter then begin

View File

@ -461,9 +461,6 @@ const
(Name: dlgFoldPasRecord; Xml: 'Record';
Index: ord(cfbtRecord); Enabled: True),
(Name: dlgFoldPasNestedComment; Xml: 'NestedComment';
Index: ord(cfbtNestedComment);Enabled: True),
(Name: dlgFoldPasIfDef; Xml: 'IfDef';
Index: ord(cfbtIfDef); Enabled: False),
(Name: dlgFoldPasUserRegion; Xml: 'UserRegion';
@ -474,7 +471,10 @@ const
(Name: dlgFoldPasBorComment; Xml: 'BorComment';
Index: ord(cfbtBorCommand); Enabled: True),
(Name: dlgFoldPasSlashComment; Xml: 'SlashComment';
Index: ord(cfbtSlashComment); Enabled: False)
Index: ord(cfbtSlashComment); Enabled: False),
(Name: dlgFoldPasNestedComment; Xml: 'NestedComment';
Index: ord(cfbtNestedComment);Enabled: True)
);
EditorOptionsFoldInfoLFM: Array [0..2] of TEditorOptionsFoldInfo
@ -1488,12 +1488,12 @@ begin
EditorOptionsFoldInfoPas[14].Name := dlgFoldPasClass;
EditorOptionsFoldInfoPas[15].Name := dlgFoldPasClassSection;
EditorOptionsFoldInfoPas[16].Name := dlgFoldPasRecord;
EditorOptionsFoldInfoPas[17].Name := dlgFoldPasNestedComment;
EditorOptionsFoldInfoPas[18].Name := dlgFoldPasIfDef;
EditorOptionsFoldInfoPas[19].Name := dlgFoldPasUserRegion;
EditorOptionsFoldInfoPas[20].Name := dlgFoldPasAnsiComment;
EditorOptionsFoldInfoPas[21].Name := dlgFoldPasBorComment;
EditorOptionsFoldInfoPas[22].Name := dlgFoldPasSlashComment;
EditorOptionsFoldInfoPas[17].Name := dlgFoldPasIfDef;
EditorOptionsFoldInfoPas[18].Name := dlgFoldPasUserRegion;
EditorOptionsFoldInfoPas[19].Name := dlgFoldPasAnsiComment;
EditorOptionsFoldInfoPas[20].Name := dlgFoldPasBorComment;
EditorOptionsFoldInfoPas[21].Name := dlgFoldPasSlashComment;
EditorOptionsFoldInfoPas[22].Name := dlgFoldPasNestedComment;
EditorOptionsFoldInfoHTML[0].Name := dlgFoldHtmlNode;
EditorOptionsFoldInfoHTML[1].Name := dlgFoldHtmlComment;

View File

@ -4,7 +4,6 @@ inherited EditorCodefoldingOptionsFrame: TEditorCodefoldingOptionsFrame
Anchors = [akTop]
ClientHeight = 352
ClientWidth = 511
TabOrder = 0
Visible = False
DesignLeft = 346
DesignTop = 366
@ -16,7 +15,7 @@ inherited EditorCodefoldingOptionsFrame: TEditorCodefoldingOptionsFrame
AnchorSideRight.Side = asrBottom
Left = 0
Height = 2
Top = 28
Top = 25
Width = 511
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Top = 6
@ -27,9 +26,9 @@ inherited EditorCodefoldingOptionsFrame: TEditorCodefoldingOptionsFrame
AnchorSideTop.Control = LanguageComboBox
AnchorSideTop.Side = asrCenter
Left = 206
Height = 18
Top = 40
Width = 98
Height = 16
Top = 34
Width = 81
BorderSpacing.Left = 6
Caption = 'LanguageLabel'
ParentColor = False
@ -38,9 +37,9 @@ inherited EditorCodefoldingOptionsFrame: TEditorCodefoldingOptionsFrame
AnchorSideLeft.Control = Owner
AnchorSideTop.Control = Owner
Left = 0
Height = 22
Height = 19
Top = 0
Width = 175
Width = 149
Caption = 'chkCodeFoldingEnabled'
TabOrder = 0
end
@ -48,11 +47,11 @@ inherited EditorCodefoldingOptionsFrame: TEditorCodefoldingOptionsFrame
AnchorSideLeft.Control = Owner
AnchorSideTop.Control = Bevel1
Left = 0
Height = 31
Top = 34
Height = 23
Top = 31
Width = 200
BorderSpacing.Top = 6
ItemHeight = 0
ItemHeight = 15
OnChange = LanguageComboBoxChange
OnExit = LanguageComboBoxExit
OnKeyDown = LanguageComboBoxKeyDown
@ -68,13 +67,13 @@ inherited EditorCodefoldingOptionsFrame: TEditorCodefoldingOptionsFrame
AnchorSideBottom.Control = Owner
AnchorSideBottom.Side = asrBottom
Left = 0
Height = 281
Top = 71
Height = 292
Top = 60
Width = 511
Anchors = [akTop, akLeft, akRight, akBottom]
BorderSpacing.Top = 6
BevelOuter = bvNone
ClientHeight = 281
ClientHeight = 292
ClientWidth = 511
TabOrder = 2
object FoldConfigCheckListBox: TCheckListBox
@ -83,17 +82,61 @@ inherited EditorCodefoldingOptionsFrame: TEditorCodefoldingOptionsFrame
AnchorSideBottom.Control = FoldConfPanel
AnchorSideBottom.Side = asrBottom
Left = 0
Height = 281
Height = 292
Top = 0
Width = 200
Anchors = [akTop, akLeft, akBottom]
ExtendedSelect = False
ItemHeight = 0
OnClick = FoldConfigCheckListBoxClick
OnClickCheck = FoldConfigCheckListBoxClickCheck
OnExit = FoldConfigCheckListBoxClickCheck
OnKeyUp = FoldConfigCheckListBoxKeyUp
TabOrder = 0
TopIndex = -1
end
object pnlFoldHide: TPanel
AnchorSideLeft.Control = FoldConfigCheckListBox
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = FoldConfPanel
Left = 206
Height = 57
Top = 0
Width = 64
AutoSize = True
BorderSpacing.Left = 6
BevelOuter = bvNone
ChildSizing.Layout = cclTopToBottomThenLeftToRight
ChildSizing.ControlsPerLine = 3
ClientHeight = 57
ClientWidth = 64
TabOrder = 1
object chkFold: TRadioButton
Left = 0
Height = 19
Top = 0
Width = 64
Caption = 'chkFold'
OnChange = chkFoldChange
TabOrder = 0
end
object chkHide: TRadioButton
Left = 0
Height = 19
Top = 19
Width = 64
Caption = 'chkHide'
OnChange = chkFoldChange
TabOrder = 1
end
object chkBoth: TRadioButton
Left = 0
Height = 19
Top = 38
Width = 64
Caption = 'chkBoth'
OnChange = chkFoldChange
TabOrder = 2
end
end
end
end

View File

@ -40,6 +40,12 @@ type
chkCodeFoldingEnabled: TCheckBox;
LanguageLabel: TLabel;
LanguageComboBox: TComboBox;
pnlFoldHide: TPanel;
chkFold: TRadioButton;
chkHide: TRadioButton;
chkBoth: TRadioButton;
procedure chkFoldChange(Sender: TObject);
procedure FoldConfigCheckListBoxClick(Sender: TObject);
procedure FoldConfigCheckListBoxClickCheck(Sender: TObject);
procedure FoldConfigCheckListBoxKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
procedure LanguageComboBoxChange(Sender: TObject);
@ -50,6 +56,8 @@ type
FHighlighters: array[TLazSyntaxHighlighter] of TSrcIDEHighlighter;
FCurHighlighter: TSrcIDEHighlighter;
FCurFoldInfo: TEditorOptionsFoldRecord;
FModeLock: Boolean;
procedure UpdateFoldHideRadio;
protected
function GetHighlighter(SynType: TLazSyntaxHighlighter;
CreateIfNotExists: Boolean): TSrcIDEHighlighter;
@ -88,6 +96,7 @@ var
ComboBox: TComboBox absolute Sender;
tp: TLazSyntaxHighlighter;
i: Integer;
Hl: TSynCustomFoldHighlighter;
begin
tp := EditorOpts.HighlighterList
[EditorOpts.HighlighterList.FindByName(ComboBox.Text)].TheType;
@ -97,23 +106,77 @@ begin
FoldConfigCheckListBox.Clear;
if not (assigned(FCurHighlighter) and
(FCurHighlighter is TSynCustomFoldHighlighter)) then exit;
Hl := TSynCustomFoldHighlighter(FCurHighlighter);
for i := 0 to FCurFoldInfo.Count - 1 do begin
FoldConfigCheckListBox.Items.add(FCurFoldInfo.Info^[i].Name);
FoldConfigCheckListBox.Checked[i] :=
TSynCustomFoldHighlighter(FCurHighlighter).FoldConfig[FCurFoldInfo.Info^[i].Index].Enabled;
Hl.FoldConfig[FCurFoldInfo.Info^[i].Index].Enabled;
end;
end;
procedure TEditorCodefoldingOptionsFrame.FoldConfigCheckListBoxClickCheck(Sender: TObject);
var
i: Integer;
Hl: TSynCustomFoldHighlighter;
begin
if not (assigned(FCurHighlighter) and
(FCurHighlighter is TSynCustomFoldHighlighter)) then exit;
Hl := TSynCustomFoldHighlighter(FCurHighlighter);
for i := 0 to FCurFoldInfo.Count - 1 do
TSynCustomFoldHighlighter(FCurHighlighter).FoldConfig[FCurFoldInfo.Info^[i].Index].Enabled
Hl.FoldConfig[FCurFoldInfo.Info^[i].Index].Enabled
:= FoldConfigCheckListBox.Checked[i];
UpdateFoldHideRadio;
end;
procedure TEditorCodefoldingOptionsFrame.UpdateFoldHideRadio;
var
i: LongInt;
AvailModes, Modes: TSynCustomFoldConfigModes;
Hl: TSynCustomFoldHighlighter;
begin
if not (assigned(FCurHighlighter) and
(FCurHighlighter is TSynCustomFoldHighlighter)) then exit;
Hl := TSynCustomFoldHighlighter(FCurHighlighter);
FModeLock := True;
i := FoldConfigCheckListBox.ItemIndex;
AvailModes := [];
Modes := [fmFold];
if i >= 0 then begin
i := FCurFoldInfo.Info^[i].Index;
AvailModes := Hl.FoldConfig[i].SupportedModes;
Modes := Hl.FoldConfig[i].Modes;
end;
chkFold.Checked := Modes = [fmFold];
chkHide.Checked := Modes = [fmHide];
chkBoth.Checked := Modes = [fmFold, fmHide];
pnlFoldHide.Enabled := AvailModes = [fmFold, fmHide];
FModeLock := False;
end;
procedure TEditorCodefoldingOptionsFrame.FoldConfigCheckListBoxClick(Sender: TObject);
begin
UpdateFoldHideRadio;
end;
procedure TEditorCodefoldingOptionsFrame.chkFoldChange(Sender: TObject);
var
Hl: TSynCustomFoldHighlighter;
Modes: TSynCustomFoldConfigModes;
i: LongInt;
begin
if FModeLock then exit;
if not (assigned(FCurHighlighter) and
(FCurHighlighter is TSynCustomFoldHighlighter)) then exit;
i := FoldConfigCheckListBox.ItemIndex;
if i < 0 then exit;
i := FCurFoldInfo.Info^[i].Index;
Hl := TSynCustomFoldHighlighter(FCurHighlighter);
Modes := [fmFold];
if chkHide.Checked then Modes := [fmHide];
if chkBoth.Checked then Modes := [fmFold, fmHide];
Hl.FoldConfig[i].Modes := Modes;
end;
procedure TEditorCodefoldingOptionsFrame.FoldConfigCheckListBoxKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
@ -159,7 +222,11 @@ end;
procedure TEditorCodefoldingOptionsFrame.Setup(ADialog: TAbstractOptionsEditorDialog);
begin
chkCodeFoldingEnabled.Caption := dlgUseCodeFolding;
chkFold.Caption := dlgCodeFoldEnableFold;
chkHide.Caption := dlgCodeFoldEnableHide;
chkBoth.Caption := dlgCodeFoldEnableBoth;
LanguageLabel.Caption := dlgLang;
FModeLock := False;
end;
procedure TEditorCodefoldingOptionsFrame.ReadSettings(
@ -168,6 +235,7 @@ var
i: Integer;
rf: TEditorOptionsFoldRecord;
begin
FModeLock := False;
with AOptions as TEditorOptions do
begin
chkCodeFoldingEnabled.Checked := UseCodeFolding;
@ -184,6 +252,7 @@ begin
LanguageComboBox.ItemIndex := 0;
LanguageComboBoxExit(LanguageComboBox);
end;
UpdateFoldHideRadio;
end;
procedure TEditorCodefoldingOptionsFrame.WriteSettings(

View File

@ -1270,6 +1270,9 @@ resourcestring
dlgFindTextatCursor = 'Find text at cursor';
dlgUseSyntaxHighlight = 'Use syntax highlight';
dlgUseCodeFolding = 'Code folding';
dlgCodeFoldEnableFold = 'Fold';
dlgCodeFoldEnableHide = 'Hide';
dlgCodeFoldEnableBoth = 'Both';
dlgCodeFoldingMouse = 'Mouse';
dlfMousePredefinedScheme = 'Use predefined scheme';
dlfNoPredefinedScheme = '< None >';