mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-09-13 13:19:18 +02:00
SynEdit Highlighter: Refactor; Highlighter now differs between Fold and Markup ranges; added Markup-Word-Pairs for repeat/try/case
git-svn-id: trunk@19144 -
This commit is contained in:
parent
2c9b6bd08a
commit
8d681fd278
@ -312,6 +312,7 @@ type
|
||||
procedure WMSetFocus(var Msg: TWMSetFocus); message WM_SETFOCUS;
|
||||
procedure WMVScroll(var Msg: {$IFDEF SYN_LAZARUS}TLMScroll{$ELSE}TWMScroll{$ENDIF}); message WM_VSCROLL;
|
||||
private
|
||||
FDividerDrawLevel: Integer;
|
||||
fFirstLine: integer;
|
||||
fBlockIndent: integer;
|
||||
FBlockSelection: TSynEditSelection;
|
||||
@ -433,6 +434,7 @@ type
|
||||
|
||||
procedure AquirePrimarySelection;
|
||||
function GetUndoList: TSynEditUndoList;
|
||||
procedure SetDividerDrawLevel(const AValue: Integer);
|
||||
procedure SurrenderPrimarySelection;
|
||||
procedure BookMarkOptionsChanged(Sender: TObject);
|
||||
procedure ComputeCaret(X, Y: Integer);
|
||||
@ -478,8 +480,6 @@ type
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
function GetCharLen(const Line: string; CharStartPos: integer): integer;
|
||||
function GetLogicalCaretXY: TPoint;
|
||||
procedure SetCFDividerDrawLevel(const AValue: Integer);
|
||||
function GetCFDividerDrawLevel : Integer;
|
||||
procedure SetLogicalCaretXY(const NewLogCaretXY: TPoint);
|
||||
procedure SetBeautifier(NewBeautifier: TSynCustomBeautifier);
|
||||
{$ENDIF}
|
||||
@ -619,7 +619,6 @@ type
|
||||
function GetTopView : Integer;
|
||||
procedure SetTopView(const AValue : Integer);
|
||||
{$ENDIF}
|
||||
procedure ListScanRanges(Sender: TObject);
|
||||
procedure Loaded; override;
|
||||
procedure MarkListChange(Sender: TObject);
|
||||
{$IFDEF SYN_MBCSSUPPORT}
|
||||
@ -929,10 +928,7 @@ type
|
||||
{$ENDIF}
|
||||
property SelectionMode: TSynSelectionMode
|
||||
read GetSelectionMode write SetSelectionMode default smNormal;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
property CFDividerDrawLevel: Integer
|
||||
read GetCFDividerDrawLevel write SetCFDividerDrawLevel;
|
||||
{$ENDIF}
|
||||
property CFDividerDrawLevel: Integer read FDividerDrawLevel write SetDividerDrawLevel;
|
||||
property TabWidth: integer read fTabWidth write SetTabWidth default 8;
|
||||
property WantTabs: boolean read fWantTabs write SetWantTabs default FALSE;
|
||||
property OnChange: TNotifyEvent read FOnChange write FOnChange;
|
||||
@ -1981,16 +1977,6 @@ begin
|
||||
Result:=PhysicalToLogicalPos(CaretXY);
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.SetCFDividerDrawLevel(const AValue: Integer);
|
||||
begin
|
||||
FFoldedLinesView.CFDividerDrawLevel := AValue;
|
||||
end;
|
||||
|
||||
function TCustomSynEdit.GetCFDividerDrawLevel : Integer;
|
||||
begin
|
||||
Result := FFoldedLinesView.CFDividerDrawLevel;
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.SetLogicalCaretXY(const NewLogCaretXY: TPoint);
|
||||
begin
|
||||
CaretXY:=LogicalToPhysicalPos(NewLogCaretXY);
|
||||
@ -2791,7 +2777,8 @@ var
|
||||
colEditorBG: TColor;
|
||||
// painting the background and the text
|
||||
rcLine, rcToken: TRect;
|
||||
CurLine: integer; // line index for the loop
|
||||
CurLine: integer; // Screen-line index for the loop
|
||||
CurTextIndex: Integer; // Current Index in text
|
||||
CurPhysPos, CurLogIndex : Integer; // Physical Start Position of next token in current Line
|
||||
TokenAccu: record
|
||||
Len, MaxLen: integer;
|
||||
@ -3314,6 +3301,7 @@ var
|
||||
CurLine := FirstLine-1;
|
||||
while CurLine<LastLine do begin
|
||||
inc(CurLine);
|
||||
CurTextIndex := FFoldedLinesView.TextIndex[CurLine];
|
||||
FTextDrawer.FrameStartX := -1;
|
||||
FTextDrawer.FrameEndX := -1;
|
||||
LastFSX := -1;
|
||||
@ -3340,44 +3328,22 @@ var
|
||||
// Initialize highlighter with line text and range info. It is
|
||||
// necessary because we probably did not scan to the end of the last
|
||||
// line - the internal highlighter range might be wrong.
|
||||
{$IFDEF DEBUGSYNRANGE}
|
||||
if (FFoldedLinesView.Ranges[CurLine] = nil) or
|
||||
(FFoldedLinesView.Ranges[CurLine] = NullRange) then begin
|
||||
debugln(['>>>> SynEdit Highlight-Ranges Error <<<< ',
|
||||
' AClip =', dbgs(AClip),
|
||||
' FirstLine=', FirstLine,' LastLine=',Lastline,
|
||||
' CurLine=',CurLine,
|
||||
' FirstCol=',FirstCol, ' LastCol=',LastCol,
|
||||
' CanvasRect=',dbgs(Canvas.ClipRect)]);
|
||||
debugln([' Topline=', FTopLine, ' LineCount=', FLines.Count,
|
||||
' FoldedTopLine=', FFoldedLinesView.TopLine,
|
||||
' foldedCount=', FFoldedLinesView.Count,
|
||||
' TextHeight=', FTextHeight,
|
||||
' Range=', PtrInt(FFoldedLinesView.Ranges[CurLine])
|
||||
]);
|
||||
DrawHiLightMarkupToken(nil, PChar(Pointer(sLine)), Length(sLine));
|
||||
end
|
||||
else begin
|
||||
{$ENDIF}
|
||||
fHighlighter.StartAtLineIndex(FFoldedLinesView.ScreenLineToTextIndex(CurLine));
|
||||
// Try to concatenate as many tokens as possible to minimize the count
|
||||
// of ExtTextOut calls necessary. This depends on the selection state
|
||||
// or the line having special colors. For spaces the foreground color
|
||||
// is ignored as well.
|
||||
//debugln('>>>> PaintLines Line=',dbgs(CurLine),' rect=',dbgs(rcToken));
|
||||
while not fHighlighter.GetEol do begin
|
||||
fHighlighter.GetTokenEx(sToken,nTokenLen);
|
||||
attr := fHighlighter.GetTokenAttribute;
|
||||
// Add Markup to the token and append it to the TokenAccu
|
||||
// record. This will paint any chars already stored if there is
|
||||
// a (visible) change in the attributes.
|
||||
DrawHiLightMarkupToken(attr,sToken,nTokenLen);
|
||||
// Let the highlighter scan the next token.
|
||||
fHighlighter.Next;
|
||||
end;
|
||||
{$IFDEF DEBUGSYNRANGE}
|
||||
fHighlighter.StartAtLineIndex(CurTextIndex);
|
||||
// Try to concatenate as many tokens as possible to minimize the count
|
||||
// of ExtTextOut calls necessary. This depends on the selection state
|
||||
// or the line having special colors. For spaces the foreground color
|
||||
// is ignored as well.
|
||||
//debugln('>>>> PaintLines Line=',dbgs(CurLine),' rect=',dbgs(rcToken));
|
||||
while not fHighlighter.GetEol do begin
|
||||
fHighlighter.GetTokenEx(sToken,nTokenLen);
|
||||
attr := fHighlighter.GetTokenAttribute;
|
||||
// Add Markup to the token and append it to the TokenAccu
|
||||
// record. This will paint any chars already stored if there is
|
||||
// a (visible) change in the attributes.
|
||||
DrawHiLightMarkupToken(attr,sToken,nTokenLen);
|
||||
// Let the highlighter scan the next token.
|
||||
fHighlighter.Next;
|
||||
end;
|
||||
{$ENDIF}
|
||||
end;
|
||||
// Draw anything that's left in the TokenAccu record. Fill to the end
|
||||
// of the invalid area with the correct colors.
|
||||
@ -3385,13 +3351,15 @@ var
|
||||
|
||||
fMarkupManager.FinishMarkupForRow(FFoldedLinesView.TextIndex[CurLine]+1);
|
||||
|
||||
// codefold draw splitter line
|
||||
if assigned(Gutter.CodeFoldPart) and Gutter.CodeFoldPart.Visible
|
||||
and (FFoldedLinesView.DrawDivider[curLine]) then
|
||||
begin
|
||||
ypos := rcToken.Bottom - 1;
|
||||
LCLIntf.MoveToEx(dc, nRightEdge, ypos, nil);
|
||||
LCLIntf.LineTo(dc, fGutterWidth - 1, ypos);
|
||||
// draw splitter line
|
||||
if Assigned(fHighlighter) then begin
|
||||
fHighlighter.DrawDividerLevel := FDividerDrawLevel;
|
||||
if (fHighlighter.DrawDivider[CurTextIndex]) then
|
||||
begin
|
||||
ypos := rcToken.Bottom - 1;
|
||||
LCLIntf.MoveToEx(dc, nRightEdge, ypos, nil);
|
||||
LCLIntf.LineTo(dc, fGutterWidth - 1, ypos);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
CurLine:=-1;
|
||||
@ -4461,15 +4429,6 @@ begin
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
procedure TCustomSynEdit.ListScanRanges(Sender: TObject);
|
||||
{$IFNDEF SYN_LAZARUS}
|
||||
var
|
||||
i: integer;
|
||||
{$ENDIF}
|
||||
begin
|
||||
ScanFrom(0,FTheLinesView.Count-1);
|
||||
end;
|
||||
|
||||
{$IFDEF SYN_MBCSSUPPORT}
|
||||
type
|
||||
TStringType = (stNone, stHalfNumAlpha, stHalfSymbol, stHalfKatakana,
|
||||
@ -4967,6 +4926,12 @@ begin
|
||||
Result := fUndoList;
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.SetDividerDrawLevel(const AValue: Integer);
|
||||
begin
|
||||
FDividerDrawLevel := AValue;
|
||||
Invalidate;
|
||||
end;
|
||||
|
||||
function TCustomSynEdit.GetLineState(ALine: Integer): TSynLineState;
|
||||
begin
|
||||
with TSynEditStringList(fLines) do
|
||||
@ -5288,6 +5253,9 @@ begin
|
||||
if Operation = opRemove then begin
|
||||
if AComponent = fHighlighter then begin
|
||||
fHighlighter := nil;
|
||||
if assigned(FLines.Ranges) then
|
||||
FLines.Ranges.Free;
|
||||
FLines.Ranges := nil;
|
||||
fMarkupHighCaret.Highlighter := nil;
|
||||
fMarkupWordGroup.Highlighter := nil;
|
||||
FFoldedLinesView.Highlighter := nil;
|
||||
@ -5309,9 +5277,10 @@ end;
|
||||
|
||||
procedure TCustomSynEdit.RemoveHooksFromHighlighter;
|
||||
begin
|
||||
if Assigned(fHighlighter) then
|
||||
fHighlighter.UnhookAttrChangeEvent
|
||||
({$IFDEF FPC}@{$ENDIF}HighlighterAttrChanged);
|
||||
if not Assigned(fHighlighter) then
|
||||
exit;
|
||||
fHighlighter.UnhookAttrChangeEvent({$IFDEF FPC}@{$ENDIF}HighlighterAttrChanged);
|
||||
fHighlighter.DetachFromLines(FLines);
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.SetHighlighter(const Value: TSynCustomHighlighter);
|
||||
@ -5322,6 +5291,7 @@ begin
|
||||
Value.HookAttrChangeEvent(
|
||||
{$IFDEF FPC}@{$ENDIF}HighlighterAttrChanged);
|
||||
Value.FreeNotification(Self);
|
||||
Value.AttachToLines(FLines);
|
||||
end;
|
||||
fHighlighter := Value;
|
||||
// Ensure to free all copies in SynEit.Notification too
|
||||
@ -5338,7 +5308,7 @@ begin
|
||||
RecalcCharExtent;
|
||||
FTheLinesView.BeginUpdate;
|
||||
try
|
||||
ListScanRanges(Self);
|
||||
ScanFrom(0,FTheLinesView.Count-1);
|
||||
finally
|
||||
FTheLinesView.EndUpdate;
|
||||
end;
|
||||
|
@ -180,23 +180,16 @@ type
|
||||
fTextIndexList : Array of integer; (* Map each Screen line into a line in textbuffer *)
|
||||
fFoldTypeList : Array of TSynEditCodeFoldType;
|
||||
fOnFoldChanged : TFoldChangedEvent;
|
||||
fCFDividerDrawLevel: Integer;
|
||||
fLockCount : Integer;
|
||||
fNeedFixFrom, fNeedFixMinEnd : Integer;
|
||||
fNeedCaretCheck : Boolean;
|
||||
|
||||
function GetCount : integer;
|
||||
function GetDrawDivider(Index : integer) : Boolean;
|
||||
function GetFoldEndLevel(Index: integer): integer;
|
||||
function GetFoldMinLevel(Index: integer): integer;
|
||||
function GetFoldNestLevel(index : Integer): integer;
|
||||
function GetLines(index : Integer) : String;
|
||||
function GetDisplayNumber(index : Integer) : Integer;
|
||||
function GetRange(Index : integer) : TSynEditRange;
|
||||
function GetTextIndex(index : Integer) : Integer;
|
||||
function GetFoldType(index : Integer) : TSynEditCodeFoldType;
|
||||
function IsFolded(index : integer) : Boolean; // TextIndex
|
||||
procedure PutRange(Index : integer; const AValue : TSynEditRange);
|
||||
procedure SetTopLine(const ALine : integer);
|
||||
function GetTopTextIndex : integer;
|
||||
procedure SetTopTextIndex(const AIndex : integer);
|
||||
@ -232,16 +225,10 @@ type
|
||||
// Attributes for Visible-Lines-On-screen
|
||||
property Lines[index : Integer] : String (* Lines on screen / 0 = TopLine *)
|
||||
read GetLines; default;
|
||||
property Ranges[Index: integer]: TSynEditRange
|
||||
read GetRange write PutRange;
|
||||
property DisplayNumber[index : Integer] : Integer (* LineNumber for display in Gutter / result is 1-based *)
|
||||
read GetDisplayNumber;
|
||||
property FoldType[index : Integer] : TSynEditCodeFoldType (* FoldIcon / State *)
|
||||
read GetFoldType;
|
||||
property FoldNestLvl[index : Integer] : integer (* FoldIcon / Deep/Level of nesting; 1 for top-lvl *)
|
||||
read GetFoldNestLevel;
|
||||
property DrawDivider[Index: integer]: Boolean
|
||||
read GetDrawDivider;
|
||||
property TextIndex[index : Integer] : Integer (* Position in SynTextBuffer / result is 0-based *)
|
||||
read GetTextIndex; // maybe writable
|
||||
|
||||
@ -255,7 +242,6 @@ type
|
||||
|
||||
property Count : integer read GetCount; (* refers to visible (unfolded) lines *)
|
||||
|
||||
property CFDividerDrawLevel: Integer read fCFDividerDrawLevel write fCFDividerDrawLevel;
|
||||
property MarkupInfoFoldedCode: TSynSelectedColor read FMarkupInfoFoldedCode;
|
||||
public
|
||||
procedure Lock;
|
||||
@ -283,10 +269,6 @@ type
|
||||
|
||||
property OnFoldChanged: TFoldChangedEvent (* reports 1-based line *) {TODO: synedit expects 0 based }
|
||||
read fOnFoldChanged write fOnFoldChanged;
|
||||
public
|
||||
// TextIndex
|
||||
property FoldMinLevel[Index: integer]: integer read GetFoldMinLevel;
|
||||
property FoldEndLevel[Index: integer]: integer read GetFoldEndLevel;
|
||||
property HighLighter: TSynCustomHighlighter read FHighLighter
|
||||
write FHighLighter;
|
||||
end;
|
||||
@ -1554,21 +1536,6 @@ begin
|
||||
Result := fLines.Count - fFoldTree.FindLastFold.FoldedBefore;
|
||||
end;
|
||||
|
||||
function TSynEditFoldedView.GetDrawDivider(Index : integer) : Boolean;
|
||||
begin
|
||||
result := (FoldType[Index] in [cfEnd])
|
||||
and (FoldEndLevel[TextIndex[index]] < CFDividerDrawLevel);
|
||||
end;
|
||||
|
||||
function TSynEditFoldedView.GetFoldNestLevel(index : Integer): integer;
|
||||
begin
|
||||
if (index < 0) or (index > fLinesInWindow) then exit(-1);
|
||||
if (fFoldTypeList[index] = cfEnd) and (fTextIndexList[index] > 0) then
|
||||
Result := FoldEndLevel[fTextIndexList[index]-1]
|
||||
else
|
||||
Result := FoldEndLevel[fTextIndexList[index]];
|
||||
end;
|
||||
|
||||
(* Topline *)
|
||||
procedure TSynEditFoldedView.SetTopLine(const ALine : integer);
|
||||
begin
|
||||
@ -1601,7 +1568,19 @@ procedure TSynEditFoldedView.CalculateMaps;
|
||||
var
|
||||
i, tpos, cnt : Integer;
|
||||
node : TSynTextFoldAVLNode;
|
||||
hl: TSynCustomFoldHighlighter;
|
||||
begin
|
||||
if not(assigned(FHighLighter) and (FHighLighter is TSynCustomFoldHighlighter))
|
||||
then begin
|
||||
for i := 0 to fLinesInWindow do begin
|
||||
fTextIndexList[i] := fTopLine + i - 1;
|
||||
fFoldTypeList[i] := cfNone;
|
||||
end;
|
||||
exit;
|
||||
end;
|
||||
|
||||
FHighLighter.CurrentLines := fLines;
|
||||
hl := TSynCustomFoldHighlighter(FHighLighter);
|
||||
node := fFoldTree.FindFoldForFoldedLine(fTopLine, true);
|
||||
// ftopline is not a folded line
|
||||
// so node.FoldedBefore(next node after ftopl) does apply
|
||||
@ -1617,13 +1596,13 @@ begin
|
||||
if (node.IsInFold) and (tpos+1 = node.StartLine)
|
||||
then fFoldTypeList[i] := cfCollapsed
|
||||
else
|
||||
if FoldEndLevel[tpos-1] > FoldMinLevel[tpos-1]
|
||||
if (hl.FoldOpenCount(tpos - 1) > 0)
|
||||
then fFoldTypeList[i] := cfExpanded
|
||||
else
|
||||
if (tpos > 1) and (FoldEndLevel[tpos-2] > FoldMinLevel[tpos-1])
|
||||
if (tpos > 1) and (hl.FoldCloseCount(tpos - 1) > 0)
|
||||
then fFoldTypeList[i] := cfEnd
|
||||
else
|
||||
if FoldEndLevel[tpos-1] > 0
|
||||
if hl.FoldNestCount(tpos - 1) > 0
|
||||
then fFoldTypeList[i] := cfContinue
|
||||
else fFoldTypeList[i] := cfNone;
|
||||
|
||||
@ -1651,13 +1630,6 @@ begin
|
||||
Result := fTextIndexList[index]+1;
|
||||
end;
|
||||
|
||||
function TSynEditFoldedView.GetRange(Index : integer) : TSynEditRange;
|
||||
begin
|
||||
if (index < 0) or (index > fLinesInWindow) then
|
||||
exit(fLines.Ranges[ScreenLineToTextIndex(Index)]);
|
||||
Result := fLines.Ranges[fTextIndexList[index]];
|
||||
end;
|
||||
|
||||
function TSynEditFoldedView.GetTextIndex(index : Integer) : Integer;
|
||||
begin
|
||||
if (index < 0) or (index > fLinesInWindow) then
|
||||
@ -1676,34 +1648,8 @@ begin
|
||||
Result := fFoldTree.FindFoldForLine(index+1).IsInFold;
|
||||
end;
|
||||
|
||||
procedure TSynEditFoldedView.PutRange(Index : integer; const AValue : TSynEditRange);
|
||||
begin
|
||||
if (index < 0) or (index > fLinesInWindow) then exit;
|
||||
fLines.Ranges[fTextIndexList[index]] := AValue;
|
||||
end;
|
||||
|
||||
(* Folding *)
|
||||
|
||||
function TSynEditFoldedView.GetFoldEndLevel(Index: integer): integer;
|
||||
begin
|
||||
if not(assigned(FHighLighter) and (FHighLighter is TSynCustomFoldHighlighter))
|
||||
then exit(0);
|
||||
FHighLighter.CurrentLines := fLines;
|
||||
Result := TSynCustomFoldHighlighter(FHighLighter).EndFoldLevel(Index) +
|
||||
TSynCustomFoldHighlighter(FHighLighter).LastLineFoldLevelFix(Index + 1);
|
||||
end;
|
||||
|
||||
function TSynEditFoldedView.GetFoldMinLevel(Index: integer): integer;
|
||||
begin
|
||||
if not(assigned(FHighLighter) and (FHighLighter is TSynCustomFoldHighlighter))
|
||||
then exit(0);
|
||||
FHighLighter.CurrentLines := fLines;
|
||||
Result := TSynCustomFoldHighlighter(FHighLighter).EndFoldLevel(Index) +
|
||||
TSynCustomFoldHighlighter(FHighLighter).LastLineFoldLevelFix(Index + 1);
|
||||
Result := Min(Result,
|
||||
TSynCustomFoldHighlighter(FHighLighter).MinimumFoldLevel(Index));
|
||||
end;
|
||||
|
||||
procedure TSynEditFoldedView.FoldAtLine(AStartLine : Integer);
|
||||
begin
|
||||
FoldAtViewPos(AStartLine + fTopLine);
|
||||
@ -1715,17 +1661,11 @@ begin
|
||||
end;
|
||||
|
||||
function TSynEditFoldedView.LengthForFoldAtTextIndex(ALine : Integer) : Integer;
|
||||
var
|
||||
i, lvl, cnt : Integer;
|
||||
begin
|
||||
cnt := fLines.Count;
|
||||
// AStartLine is 1-based // FoldEndLevel is 0-based
|
||||
lvl := FoldEndLevel[ALine];
|
||||
i := ALine+1;
|
||||
while (i < cnt) and (FoldMinLevel[i] >= lvl) do inc(i);
|
||||
// check if fold last line of block (not mixed "end begin")
|
||||
if (i < cnt) and (FoldEndLevel[i] <= FoldMinLevel[i]) then inc(i);
|
||||
Result := i-ALine-1;
|
||||
if not(assigned(FHighLighter) and (FHighLighter is TSynCustomFoldHighlighter))
|
||||
then exit(0);
|
||||
Result := TSynCustomFoldHighlighter(FHighLighter).FoldLineLength(ALine,
|
||||
TSynCustomFoldHighlighter(FHighLighter).FoldOpenCount(ALine) -1);
|
||||
end;
|
||||
|
||||
procedure TSynEditFoldedView.FoldAtTextIndex(AStartIndex : Integer);
|
||||
@ -1780,13 +1720,19 @@ end;
|
||||
procedure TSynEditFoldedView.FoldAll(StartLevel : Integer = 0; IgnoreNested : Boolean = False);
|
||||
var
|
||||
i, l, top: Integer;
|
||||
hl: TSynCustomFoldHighlighter;
|
||||
begin
|
||||
if not(assigned(FHighLighter) and (FHighLighter is TSynCustomFoldHighlighter))
|
||||
then exit;
|
||||
FHighLighter.CurrentLines := fLines;
|
||||
hl := TSynCustomFoldHighlighter(FHighLighter);
|
||||
|
||||
top := TopTextIndex;
|
||||
fFoldTree.Clear;
|
||||
i := 0;
|
||||
while i < fLines.Count do begin
|
||||
if (FoldEndLevel[i] > FoldMinLevel[i])
|
||||
and (FoldEndLevel[i] > StartLevel) then begin
|
||||
if (hl.FoldOpenCount(i) > 0)
|
||||
and (hl.FoldNestCount(i) > StartLevel) then begin
|
||||
l := LengthForFoldAtTextIndex(i);
|
||||
// i is 0-based
|
||||
// FoldTree is 1-based AND first line remains visble
|
||||
@ -1807,6 +1753,7 @@ var
|
||||
line, cnt, a: Integer;
|
||||
LastStart, LastCount: Integer;
|
||||
node, tmpnode: TSynTextFoldAVLNode;
|
||||
hl: TSynCustomFoldHighlighter;
|
||||
begin
|
||||
Result := false;
|
||||
if fLockCount > 0 then begin
|
||||
@ -1825,6 +1772,11 @@ begin
|
||||
end;
|
||||
If AMinEnd < node.StartLine then AMinEnd := node.StartLine;
|
||||
|
||||
if not(assigned(FHighLighter) and (FHighLighter is TSynCustomFoldHighlighter))
|
||||
then exit;
|
||||
FHighLighter.CurrentLines := fLines;
|
||||
hl := TSynCustomFoldHighlighter(FHighLighter);
|
||||
|
||||
// LineCount is allowed to be -1
|
||||
while node.IsInFold and (node.StartLine + node.LineCount + 1 >= AStart) do begin
|
||||
tmpnode := node.Prev;
|
||||
@ -1851,7 +1803,7 @@ begin
|
||||
LastCount := cnt;
|
||||
|
||||
// look at the 0-based cfCollapsed (visible) Line
|
||||
if not(FoldEndLevel[line -1] > FoldMinLevel[line - 1]) then begin
|
||||
if not(hl.FoldOpenCount(line - 1) > 0) then begin
|
||||
// the Fold-Begin of this node has gone
|
||||
tmpnode := node.Prev;
|
||||
aFoldTree.RemoveFoldForNodeAtLine(node, -1); // Don't touch any nested node
|
||||
@ -1917,36 +1869,35 @@ function TSynEditFoldedView.ExpandedLineForBlockAtLine(ALine : Integer) : Intege
|
||||
var
|
||||
i, l : Integer;
|
||||
node: TSynTextFoldAVLNode;
|
||||
hl: TSynCustomFoldHighlighter;
|
||||
begin
|
||||
Result := -1;
|
||||
i := ALine-1;
|
||||
if not(assigned(FHighLighter) and (FHighLighter is TSynCustomFoldHighlighter))
|
||||
then exit;
|
||||
FHighLighter.CurrentLines := fLines;
|
||||
hl := TSynCustomFoldHighlighter(FHighLighter);
|
||||
|
||||
if (i>0) and (FoldMinLevel[i] < FoldEndLevel[i-1])then begin
|
||||
if FoldMinLevel[i] < FoldEndLevel[i] then begin
|
||||
// this is a combined "end begin" line
|
||||
node := fFoldTree.FindFoldForLine(ALine, true);
|
||||
if node.IsInFold and (node.StartLine = ALine +1) then
|
||||
dec(i);
|
||||
if i < 0 then exit;
|
||||
end else begin
|
||||
// this is a "end" line
|
||||
dec(i);
|
||||
end;
|
||||
l := FoldEndLevel[i];
|
||||
end else if FoldEndLevel[i] = 0 then
|
||||
exit
|
||||
else begin
|
||||
// check if current line is cfCollapsed
|
||||
i := ALine;
|
||||
if hl.FoldOpenCount(i - 1) > 0 then begin
|
||||
node := fFoldTree.FindFoldForLine(ALine, true);
|
||||
if node.IsInFold and (node.StartLine = ALine +1) then
|
||||
dec(i);
|
||||
if i < 0 then exit;
|
||||
l := FoldEndLevel[i]
|
||||
end;
|
||||
|
||||
while (i > 0) and (FoldMinLevel[i] >= l) do
|
||||
dec(i)
|
||||
else
|
||||
exit(ALine);
|
||||
end
|
||||
else if hl.FoldCloseCount(i - 1) > 0 then
|
||||
dec(i);
|
||||
if (FoldEndLevel[i] > 0) then // TODO, check for collapsed at index = 0
|
||||
if (i < 0) or (hl.FoldNestCount(i-1) = 0) then
|
||||
exit;
|
||||
|
||||
l := 0;
|
||||
while (i > 0) and (l >= 0) do begin // (FoldMinLevel[i] >= l) do
|
||||
dec(i);
|
||||
l := l - hl.FoldOpenCount(i);
|
||||
if l >= 0 then
|
||||
l := l + hl.FoldCloseCount(i);
|
||||
end;
|
||||
if (hl.FoldNestCount(i) > 0) then // TODO, check for collapsed at index = 0
|
||||
Result := i + 1;
|
||||
end;
|
||||
|
||||
|
@ -59,6 +59,18 @@ type
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
{ TSynHighlighterRangeList }
|
||||
|
||||
TSynHighlighterRangeList = class(TSynEditStorageMem)
|
||||
private
|
||||
function GetRange(Index: Integer): Pointer;
|
||||
procedure SetRange(Index: Integer; const AValue: Pointer);
|
||||
protected
|
||||
function ItemSize: Integer; override;
|
||||
public
|
||||
property Range[Index: Integer]: Pointer read GetRange write SetRange; default;
|
||||
end;
|
||||
|
||||
{ TSynHighlighterAttributes }
|
||||
|
||||
TSynHighlighterAttributes = class(TPersistent)
|
||||
@ -154,11 +166,15 @@ type
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
FCapabilities: TSynHighlighterCapabilities;
|
||||
FCurrentLines: TSynEditStrings;
|
||||
FCurrentRanges: TSynHighlighterRangeList;
|
||||
FDrawDividerLevel: Integer;
|
||||
FLineIndex: Integer;
|
||||
{$ENDIF}
|
||||
fUpdateCount: integer; //mh 2001-09-13
|
||||
fEnabled: Boolean;
|
||||
fWordBreakChars: TSynIdentChars;
|
||||
procedure SetCurrentLines(const AValue: TSynEditStrings);
|
||||
procedure SetDrawDividerLevel(const AValue: Integer);
|
||||
procedure SetEnabled(const Value: boolean); //DDH 2001-10-23
|
||||
protected
|
||||
fDefaultFilter: string;
|
||||
@ -177,8 +193,12 @@ type
|
||||
procedure SetAttributesOnChange(AEvent: TNotifyEvent);
|
||||
procedure SetDefaultFilter(Value: string); virtual;
|
||||
procedure SetSampleSource(Value: string); virtual;
|
||||
function CreateRangeList: TSynHighlighterRangeList; virtual;
|
||||
function UpdateRangeInfoAtLine(Index: Integer): Boolean; virtual; // Returns true if range changed
|
||||
// code fold - only valid if hcCodeFolding in Capabilities
|
||||
property LineIndex: Integer read FLineIndex;
|
||||
property CurrentRanges: TSynHighlighterRangeList read FCurrentRanges;
|
||||
function GetDrawDivider(Index: integer): Boolean; virtual;
|
||||
public
|
||||
procedure DefHighlightChange(Sender: TObject);
|
||||
{$IFNDEF SYN_CPPB_1} class {$ENDIF}
|
||||
@ -194,6 +214,8 @@ type
|
||||
procedure Assign(Source: TPersistent); override;
|
||||
procedure BeginUpdate;
|
||||
procedure EndUpdate;
|
||||
procedure AttachToLines(Lines: TSynEditStrings);
|
||||
procedure DetachFromLines(Lines: TSynEditStrings);
|
||||
public
|
||||
function GetEol: Boolean; virtual; abstract;
|
||||
function GetRange: Pointer; virtual;
|
||||
@ -206,13 +228,21 @@ type
|
||||
procedure Next; virtual; abstract;
|
||||
procedure NextToEol;
|
||||
|
||||
property DrawDivider[Index: integer]: Boolean read GetDrawDivider;
|
||||
property DrawDividerLevel: Integer read FDrawDividerLevel write SetDrawDividerLevel;
|
||||
public
|
||||
property CurrentLines: TSynEditStrings read FCurrentLines write SetCurrentLines;
|
||||
|
||||
procedure StartAtLineIndex(LineNumber:Integer); virtual; // 0 based
|
||||
procedure ContinueNextLine; // To be called at EOL; does not read the range
|
||||
|
||||
function ScanFrom(Index: integer; AtLeastTilIndex: integer = -1): integer;
|
||||
procedure SetRange(Value: Pointer); virtual;
|
||||
procedure ResetRange; virtual;
|
||||
procedure SetLine({$IFDEF FPC}const {$ENDIF}NewValue: String;
|
||||
LineNumber:Integer // 0 based
|
||||
); virtual;
|
||||
procedure StartAtLineIndex(LineNumber:Integer); // 0 based
|
||||
procedure ContinueNextLine; // To be called at EOL; does not read the range
|
||||
|
||||
public
|
||||
function UseUserSettings(settingIndex: integer): boolean; virtual;
|
||||
procedure EnumUserSettings(Settings: TStrings); virtual;
|
||||
@ -225,13 +255,6 @@ type
|
||||
property IdentChars: TSynIdentChars read GetIdentChars;
|
||||
property WordBreakChars: TSynIdentChars read fWordBreakChars write SetWordBreakChars;
|
||||
property LanguageName: string read GetLanguageName;
|
||||
property CurrentLines: TSynEditStrings read FCurrentLines write FCurrentLines;
|
||||
|
||||
function ScanFrom(Index: integer; AtLeastTilIndex: integer = -1): integer;
|
||||
(* Methds for folding *)
|
||||
function MinimumCodeFoldBlockLevel: integer; virtual;
|
||||
function CurrentCodeFoldBlockLevel: integer; virtual;
|
||||
function LastLineCodeFoldLevelFix: integer; virtual;
|
||||
public
|
||||
property AttrCount: integer read GetAttribCount;
|
||||
property Attribute[idx: integer]: TSynHighlighterAttributes
|
||||
@ -833,6 +856,18 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TSynCustomHighlighter.AttachToLines(Lines: TSynEditStrings);
|
||||
begin
|
||||
Lines.Ranges := CreateRangeList;
|
||||
end;
|
||||
|
||||
procedure TSynCustomHighlighter.DetachFromLines(Lines: TSynEditStrings);
|
||||
begin
|
||||
if assigned(Lines.Ranges) then
|
||||
Lines.Ranges.Free;
|
||||
Lines.Ranges := nil;
|
||||
end;
|
||||
|
||||
procedure TSynCustomHighlighter.FreeHighlighterAttributes;
|
||||
var
|
||||
i: integer;
|
||||
@ -1067,7 +1102,7 @@ begin
|
||||
if LineNumber = 0 then
|
||||
ResetRange
|
||||
else
|
||||
SetRange(CurrentLines.Ranges[LineNumber - 1]);
|
||||
SetRange(FCurrentRanges[LineNumber - 1]);
|
||||
SetLine(CurrentLines[LineNumber], LineNumber);
|
||||
end;
|
||||
|
||||
@ -1106,11 +1141,26 @@ procedure TSynCustomHighlighter.SetSampleSource(Value: string);
|
||||
begin
|
||||
end;
|
||||
|
||||
function TSynCustomHighlighter.CreateRangeList: TSynHighlighterRangeList;
|
||||
begin
|
||||
Result := TSynHighlighterRangeList.Create;
|
||||
end;
|
||||
|
||||
procedure TSynCustomHighlighter.UnhookAttrChangeEvent(ANotifyEvent: TNotifyEvent);
|
||||
begin
|
||||
fAttrChangeHooks.Remove(ANotifyEvent);
|
||||
end;
|
||||
|
||||
function TSynCustomHighlighter.UpdateRangeInfoAtLine(Index: Integer): Boolean;
|
||||
var
|
||||
r: Pointer;
|
||||
begin
|
||||
r := GetRange;
|
||||
Result := r <> FCurrentRanges[Index];
|
||||
if Result then
|
||||
FCurrentRanges[Index] := r;
|
||||
end;
|
||||
|
||||
function TSynCustomHighlighter.ScanFrom(Index: integer; AtLeastTilIndex: integer): integer;
|
||||
var
|
||||
c: LongInt;
|
||||
@ -1119,10 +1169,9 @@ begin
|
||||
c := CurrentLines.Count;
|
||||
StartAtLineIndex(Result);
|
||||
NextToEol;
|
||||
while (GetRange <> CurrentLines.Ranges[Result]) or
|
||||
while UpdateRangeInfoAtLine(Result) or
|
||||
(Result <= AtLeastTilIndex+1)
|
||||
do begin
|
||||
CurrentLines.Ranges[Result] := GetRange;
|
||||
inc(Result);
|
||||
if Result = c then
|
||||
break;
|
||||
@ -1131,11 +1180,6 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function TSynCustomHighlighter.MinimumCodeFoldBlockLevel: integer;
|
||||
begin
|
||||
Result := 0;
|
||||
end;
|
||||
|
||||
procedure TSynCustomHighlighter.SetEnabled(const Value: boolean);
|
||||
begin
|
||||
if fEnabled <> Value then
|
||||
@ -1148,14 +1192,41 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function TSynCustomHighlighter.LastLineCodeFoldLevelFix: integer;
|
||||
procedure TSynCustomHighlighter.SetCurrentLines(const AValue: TSynEditStrings);
|
||||
begin
|
||||
Result := 0;
|
||||
if AValue = FCurrentLines then
|
||||
exit;
|
||||
FCurrentLines := AValue;
|
||||
FCurrentRanges := TSynHighlighterRangeList(AValue.Ranges);
|
||||
end;
|
||||
|
||||
function TSynCustomHighlighter.CurrentCodeFoldBlockLevel: integer;
|
||||
procedure TSynCustomHighlighter.SetDrawDividerLevel(const AValue: Integer);
|
||||
begin
|
||||
Result := 0;
|
||||
if FDrawDividerLevel = AValue then exit;
|
||||
FDrawDividerLevel := AValue;
|
||||
//DefHighlightChange(Self);
|
||||
end;
|
||||
|
||||
function TSynCustomHighlighter.GetDrawDivider(Index: integer): Boolean;
|
||||
begin
|
||||
result := false;
|
||||
end;
|
||||
|
||||
{ TSynHighlighterRangeList }
|
||||
|
||||
function TSynHighlighterRangeList.GetRange(Index: Integer): Pointer;
|
||||
begin
|
||||
Result := Pointer(ItemPointer[Index]^);
|
||||
end;
|
||||
|
||||
procedure TSynHighlighterRangeList.SetRange(Index: Integer; const AValue: Pointer);
|
||||
begin
|
||||
Pointer(ItemPointer[Index]^) := AValue;
|
||||
end;
|
||||
|
||||
function TSynHighlighterRangeList.ItemSize: Integer;
|
||||
begin
|
||||
Result := SizeOf(Pointer);
|
||||
end;
|
||||
|
||||
initialization
|
||||
|
@ -71,7 +71,8 @@ type
|
||||
|
||||
TSynCustomHighlighterRange = class
|
||||
private
|
||||
FCodeFoldStackSize: integer;
|
||||
FCodeFoldStackSize: integer; // EndLevel
|
||||
FMinimumCodeFoldBlockLevel: integer;
|
||||
FRangeType: Pointer;
|
||||
FTop: TSynCustomCodeFoldBlock;
|
||||
public
|
||||
@ -79,8 +80,8 @@ type
|
||||
destructor Destroy; override;
|
||||
function Compare(Range: TSynCustomHighlighterRange): integer; virtual;
|
||||
function Add(ABlockType: Pointer = nil; IncreaseLevel: Boolean = True):
|
||||
TSynCustomCodeFoldBlock;
|
||||
procedure Pop(DecreaseLevel: Boolean = True);
|
||||
TSynCustomCodeFoldBlock; virtual;
|
||||
procedure Pop(DecreaseLevel: Boolean = True); virtual;
|
||||
procedure Clear; virtual;
|
||||
procedure Assign(Src: TSynCustomHighlighterRange); virtual;
|
||||
procedure WriteDebugReport;
|
||||
@ -88,6 +89,8 @@ type
|
||||
public
|
||||
property RangeType: Pointer read FRangeType write FRangeType;
|
||||
property CodeFoldStackSize: integer read FCodeFoldStackSize;
|
||||
property MinimumCodeFoldBlockLevel: integer
|
||||
read FMinimumCodeFoldBlockLevel write FMinimumCodeFoldBlockLevel;
|
||||
property Top: TSynCustomCodeFoldBlock read FTop;
|
||||
end;
|
||||
TSynCustomHighlighterRangeClass = class of TSynCustomHighlighterRange;
|
||||
@ -115,8 +118,6 @@ type
|
||||
FCodeFoldRange: TSynCustomHighlighterRange;
|
||||
fRanges: TSynCustomHighlighterRanges;
|
||||
FRootCodeFoldBlock: TSynCustomCodeFoldBlock;
|
||||
protected
|
||||
FMinimumCodeFoldBlockLevel: integer;
|
||||
protected
|
||||
function GetFoldNodeInfo(Line, Index: Integer): TSynFoldNodeInfo; virtual;
|
||||
function GetFoldNodeInfoCount(Line: Integer): Integer; virtual;
|
||||
@ -134,14 +135,21 @@ type
|
||||
destructor Destroy; override;
|
||||
function GetRange: Pointer; override;
|
||||
|
||||
function MinimumCodeFoldBlockLevel: integer; override;
|
||||
function CurrentCodeFoldBlockLevel: integer; override;
|
||||
function MinimumCodeFoldBlockLevel: integer; virtual;
|
||||
function CurrentCodeFoldBlockLevel: integer; virtual;
|
||||
|
||||
// requires CurrentLines;
|
||||
function MinimumFoldLevel(Index: Integer): integer; virtual; abstract;
|
||||
function EndFoldLevel(Index: Integer): integer; virtual; abstract;
|
||||
function LastLineFoldLevelFix(Index: Integer): integer; virtual; abstract;
|
||||
|
||||
// fold-nodes that can be collapsed
|
||||
// Highlighter can join several fold structures Or leave out some
|
||||
function FoldOpenCount(ALineIndex: Integer): integer; virtual;
|
||||
function FoldCloseCount(ALineIndex: Integer): integer; virtual;
|
||||
function FoldNestCount(ALineIndex: Integer): integer; virtual;
|
||||
function FoldLineLength(ALineIndex, FoldIndex: Integer): integer; virtual;
|
||||
|
||||
// All fold-nodes
|
||||
property FoldNodeInfo[Line, Index: Integer]: TSynFoldNodeInfo read GetFoldNodeInfo;
|
||||
property FoldNodeInfoCount[Line: Integer]: Integer read GetFoldNodeInfoCount;
|
||||
|
||||
@ -258,7 +266,7 @@ end;
|
||||
|
||||
function TSynCustomFoldHighlighter.MinimumCodeFoldBlockLevel: integer;
|
||||
begin
|
||||
Result := FMinimumCodeFoldBlockLevel;
|
||||
Result := FCodeFoldRange.MinimumCodeFoldBlockLevel;
|
||||
end;
|
||||
|
||||
procedure TSynCustomFoldHighlighter.SetRange(Value: Pointer);
|
||||
@ -267,14 +275,13 @@ begin
|
||||
// in case we asigned a null range
|
||||
if not assigned(FCodeFoldRange.FoldRoot) then
|
||||
FCodeFoldRange.FoldRoot := FRootCodeFoldBlock;
|
||||
FMinimumCodeFoldBlockLevel:=FCodeFoldRange.CodeFoldStackSize;
|
||||
end;
|
||||
|
||||
procedure TSynCustomFoldHighlighter.SetLine(const NewValue: String;
|
||||
LineNumber: Integer);
|
||||
begin
|
||||
inherited;
|
||||
FMinimumCodeFoldBlockLevel:=CodeFoldRange.CodeFoldStackSize;
|
||||
FCodeFoldRange.MinimumCodeFoldBlockLevel := FCodeFoldRange.FCodeFoldStackSize;
|
||||
end;
|
||||
|
||||
function TSynCustomFoldHighlighter.CurrentCodeFoldBlockLevel: integer;
|
||||
@ -285,6 +292,26 @@ begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function TSynCustomFoldHighlighter.FoldOpenCount(ALineIndex: Integer): integer;
|
||||
begin
|
||||
result := 0;
|
||||
end;
|
||||
|
||||
function TSynCustomFoldHighlighter.FoldCloseCount(ALineIndex: Integer): integer;
|
||||
begin
|
||||
result := 0;
|
||||
end;
|
||||
|
||||
function TSynCustomFoldHighlighter.FoldNestCount(ALineIndex: Integer): integer;
|
||||
begin
|
||||
Result := 0;
|
||||
end;
|
||||
|
||||
function TSynCustomFoldHighlighter.FoldLineLength(ALineIndex, FoldIndex: Integer): integer;
|
||||
begin
|
||||
result := 0;
|
||||
end;
|
||||
|
||||
function TSynCustomFoldHighlighter.GetFoldNodeInfoCount(Line: Integer): Integer;
|
||||
begin
|
||||
Result := 0;
|
||||
@ -317,8 +344,6 @@ end;
|
||||
procedure TSynCustomFoldHighlighter.EndCodeFoldBlock(DecreaseLevel: Boolean = True);
|
||||
begin
|
||||
CodeFoldRange.Pop(DecreaseLevel);
|
||||
if FMinimumCodeFoldBlockLevel>CodeFoldRange.CodeFoldStackSize then
|
||||
FMinimumCodeFoldBlockLevel:=CodeFoldRange.CodeFoldStackSize;
|
||||
end;
|
||||
|
||||
procedure TSynCustomFoldHighlighter.CreateRootCodeFoldBlock;
|
||||
@ -538,16 +563,19 @@ end;
|
||||
function TSynCustomHighlighterRange.Compare(Range: TSynCustomHighlighterRange
|
||||
): integer;
|
||||
begin
|
||||
if RangeType<Range.RangeType then
|
||||
if RangeType < Range.RangeType then
|
||||
Result:=1
|
||||
else if RangeType>Range.RangeType then
|
||||
else if RangeType > Range.RangeType then
|
||||
Result:=-1
|
||||
else if Pointer(FTop) < Pointer(Range.FTop) then
|
||||
Result:= -1
|
||||
else if Pointer(FTop) > Pointer(Range.FTop) then
|
||||
Result:= 1
|
||||
else
|
||||
Result := 0;
|
||||
Result := FMinimumCodeFoldBlockLevel - Range.FMinimumCodeFoldBlockLevel;
|
||||
if Result <> 0 then
|
||||
exit;
|
||||
Result := FCodeFoldStackSize - Range.FCodeFoldStackSize;
|
||||
end;
|
||||
|
||||
function TSynCustomHighlighterRange.Add(ABlockType: Pointer;
|
||||
@ -568,6 +596,8 @@ begin
|
||||
FTop := FTop.Parent;
|
||||
if DecreaseLevel then
|
||||
dec(FCodeFoldStackSize);
|
||||
if FMinimumCodeFoldBlockLevel > FCodeFoldStackSize then
|
||||
FMinimumCodeFoldBlockLevel := FCodeFoldStackSize;
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -575,6 +605,7 @@ procedure TSynCustomHighlighterRange.Clear;
|
||||
begin
|
||||
FRangeType:=nil;
|
||||
FCodeFoldStackSize := 0;
|
||||
FMinimumCodeFoldBlockLevel := 0;
|
||||
FTop:=nil;
|
||||
end;
|
||||
|
||||
@ -583,11 +614,13 @@ begin
|
||||
if (Src<>nil) and (Src<>TSynCustomHighlighterRange(NullRange)) then begin
|
||||
FTop := Src.FTop;
|
||||
FCodeFoldStackSize := Src.FCodeFoldStackSize;
|
||||
FMinimumCodeFoldBlockLevel := Src.FMinimumCodeFoldBlockLevel;
|
||||
FRangeType := Src.FRangeType;
|
||||
end
|
||||
else begin
|
||||
FTop := nil;
|
||||
FCodeFoldStackSize := 0;
|
||||
FMinimumCodeFoldBlockLevel := 0;
|
||||
FRangeType := nil;
|
||||
end;
|
||||
end;
|
||||
@ -634,6 +667,7 @@ begin
|
||||
// add a copy
|
||||
Result:=TSynCustomHighlighterRangeClass(Range.ClassType).Create(Range);
|
||||
FItems.Add(Result);
|
||||
//if FItems.Count mod 32 = 0 then debugln(['FOLDRANGE Count=', FItems.Count]);
|
||||
end;
|
||||
//debugln('TSynCustomHighlighterRanges.GetEqual A ',dbgs(Node),' ',dbgs(Result.Compare(Range)),' ',dbgs(Result.CodeFoldStackSize));
|
||||
end;
|
||||
|
@ -42,6 +42,30 @@ type
|
||||
|
||||
type
|
||||
|
||||
|
||||
{ TSynEditStorageMem }
|
||||
|
||||
TSynEditStorageMem = class
|
||||
private
|
||||
FMem: PByte;
|
||||
FCount, FCapacity: Integer;
|
||||
function GetItemPointer(Index: Integer): Pointer;
|
||||
protected
|
||||
procedure SetCapacity(const AValue: Integer); virtual;
|
||||
procedure SetCount(const AValue: Integer); virtual;
|
||||
function ItemSize: Integer; virtual; abstract;
|
||||
|
||||
property Mem: PByte read FMem;
|
||||
property ItemPointer[Index: Integer]: Pointer read GetItemPointer;
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
procedure Move(AFrom, ATo, ALen: Integer); virtual;
|
||||
property Capacity: Integer read FCapacity write SetCapacity;
|
||||
// Count must be maintained by owner
|
||||
property Count: Integer read FCount write SetCount;
|
||||
end;
|
||||
|
||||
{ TSynEditStrings }
|
||||
|
||||
TSynEditStrings = class(TStrings)
|
||||
@ -49,8 +73,8 @@ type
|
||||
FIsUtf8: Boolean;
|
||||
function GetIsUtf8 : Boolean; virtual;
|
||||
procedure SetIsUtf8(const AValue : Boolean); virtual;
|
||||
function GetRange(Index: integer): TSynEditRange; virtual; abstract;
|
||||
procedure PutRange(Index: integer; ARange: TSynEditRange); virtual; abstract;
|
||||
function GetRange: TSynEditStorageMem; virtual; abstract;
|
||||
procedure PutRange(ARange: TSynEditStorageMem); virtual; abstract;
|
||||
function GetAttribute(const Owner: TClass; const Index: Integer): Pointer; virtual; abstract;
|
||||
procedure SetAttribute(const Owner: TClass; const Index: Integer; const AValue: Pointer); virtual; abstract;
|
||||
|
||||
@ -103,7 +127,7 @@ type
|
||||
property ExpandedStrings[Index: integer]: string read GetExpandedString;
|
||||
property LengthOfLongestLine: integer read GetLengthOfLongestLine;
|
||||
property IsUtf8: Boolean read GetIsUtf8 write SetIsUtf8;
|
||||
property Ranges[Index: integer]: TSynEditRange read GetRange write PutRange;
|
||||
property Ranges: TSynEditStorageMem read GetRange write PutRange;
|
||||
end;
|
||||
|
||||
{ TSynEditStringsLinked }
|
||||
@ -115,8 +139,8 @@ type
|
||||
function GetIsUtf8 : Boolean; override;
|
||||
procedure SetIsUtf8(const AValue : Boolean); override;
|
||||
|
||||
function GetRange(Index: integer): TSynEditRange; override;
|
||||
procedure PutRange(Index: integer; ARange: TSynEditRange); override;
|
||||
function GetRange: TSynEditStorageMem; override;
|
||||
procedure PutRange(ARange: TSynEditStorageMem); override;
|
||||
|
||||
function GetAttribute(const Owner: TClass; const Index: Integer): Pointer; override;
|
||||
procedure SetAttribute(const Owner: TClass; const Index: Integer; const AValue: Pointer); override;
|
||||
@ -451,14 +475,14 @@ begin
|
||||
end;
|
||||
|
||||
//Ranges
|
||||
function TSynEditStringsLinked.GetRange(Index: integer): TSynEditRange;
|
||||
function TSynEditStringsLinked.GetRange: TSynEditStorageMem;
|
||||
begin
|
||||
Result:= fSynStrings.Ranges[Index];
|
||||
Result:= fSynStrings.Ranges;
|
||||
end;
|
||||
|
||||
procedure TSynEditStringsLinked.PutRange(Index: integer; ARange: TSynEditRange);
|
||||
procedure TSynEditStringsLinked.PutRange(ARange: TSynEditStorageMem);
|
||||
begin
|
||||
fSynStrings.Ranges[Index] := ARange;
|
||||
fSynStrings.Ranges := ARange;
|
||||
end;
|
||||
|
||||
function TSynEditStringsLinked.GetAttribute(const Owner: TClass; const Index: Integer): Pointer;
|
||||
@ -985,5 +1009,54 @@ begin
|
||||
Result := FItems[FCount];
|
||||
end;
|
||||
|
||||
{ TSynEditStorageMem }
|
||||
|
||||
function TSynEditStorageMem.GetItemPointer(Index: Integer): Pointer;
|
||||
begin
|
||||
Result := Pointer(FMem + Index * ItemSize);
|
||||
end;
|
||||
|
||||
procedure TSynEditStorageMem.SetCapacity(const AValue: Integer);
|
||||
begin
|
||||
if FCapacity = AValue then exit;
|
||||
FMem := ReallocMem(FMem, AValue * ItemSize);
|
||||
if AValue > FCapacity then
|
||||
FillChar((FMem+FCapacity*ItemSize)^, (AValue-FCapacity)*ItemSize, 0);
|
||||
FCapacity := AValue;
|
||||
end;
|
||||
|
||||
procedure TSynEditStorageMem.SetCount(const AValue: Integer);
|
||||
begin
|
||||
FCount := AValue;
|
||||
end;
|
||||
|
||||
constructor TSynEditStorageMem.Create;
|
||||
begin
|
||||
FCapacity := 0;
|
||||
FCount := 0;
|
||||
end;
|
||||
|
||||
destructor TSynEditStorageMem.Destroy;
|
||||
begin
|
||||
SetCount(0);
|
||||
SetCapacity(0);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TSynEditStorageMem.Move(AFrom, ATo, ALen: Integer);
|
||||
var
|
||||
len: Integer;
|
||||
begin
|
||||
if ATo < AFrom then begin
|
||||
Len := Min(ALen, AFrom-ATo);
|
||||
System.Move((FMem+AFrom*ItemSize)^, (FMem+ATo*ItemSize)^, Alen*ItemSize);
|
||||
FillChar((FMem+(AFrom+ALen-Len)*ItemSize)^, Len*ItemSize, 0);
|
||||
end else begin
|
||||
Len := Min(ALen, ATo-AFrom);
|
||||
System.Move((FMem+AFrom*ItemSize)^, (FMem+ATo*ItemSize)^, Alen*ItemSize);
|
||||
FillChar((FMem+AFrom*ItemSize)^, Len*ItemSize, 0);
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
@ -50,7 +50,6 @@ const
|
||||
NullRange = TSynEditRange(-1);
|
||||
|
||||
type
|
||||
TSynEditRangeClass = class end; // For Register
|
||||
TSynEditFlagsClass = class end; // For Register
|
||||
|
||||
TSynEditStringFlag = (
|
||||
@ -75,38 +74,36 @@ type
|
||||
Procedure CallRangeNotifyEvents(Sender: TSynEditStrings; aIndex, aCount: Integer);
|
||||
end;
|
||||
|
||||
|
||||
{ TSynEditStringMemory }
|
||||
|
||||
TSynEditStringMemory = class
|
||||
TSynEditStringMemory = class(TSynEditStorageMem)
|
||||
private
|
||||
FMem: ^Byte;
|
||||
FCount, FCapacity: Integer;
|
||||
FAttributeSize: Integer;
|
||||
FRangeList: TSynEditStorageMem;
|
||||
function GetAttribute(Index: Integer; Pos: Integer; Size: Word): Pointer;
|
||||
function GetAttributeSize: Integer;
|
||||
function GetCapacity: Integer;
|
||||
function GetObject(Index: Integer): TObject;
|
||||
function GetString(Index: Integer): String;
|
||||
procedure SetAttribute(Index: Integer; Pos: Integer; Size: Word; const AValue: Pointer);
|
||||
procedure SetAttributeSize(const AValue: Integer);
|
||||
procedure SetCapacity(const AValue: Integer);
|
||||
procedure SetCount(const AValue: Integer);
|
||||
procedure SetCount(const AValue: Integer); override;
|
||||
procedure SetObject(Index: Integer; const AValue: TObject);
|
||||
procedure SetRangeList(const AValue: TSynEditStorageMem);
|
||||
procedure SetString(Index: Integer; const AValue: String);
|
||||
protected
|
||||
function ItemSize: Integer; override;
|
||||
procedure SetCapacity(const AValue: Integer); override;
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
procedure Move(AFrom, ATo, ALen: Integer);
|
||||
procedure Move(AFrom, ATo, ALen: Integer); override;
|
||||
|
||||
property Strings[Index: Integer]: String read GetString write SetString; default;
|
||||
property Objects[Index: Integer]: TObject read GetObject write SetObject;
|
||||
property Attribute[Index: Integer; Pos: Integer; Size: Word]: Pointer
|
||||
read GetAttribute write SetAttribute;
|
||||
property Capacity: Integer read GetCapacity write SetCapacity;
|
||||
// Count must be maintained by owner
|
||||
property Count: Integer read FCount write SetCount;
|
||||
property AttributeSize: Integer read GetAttributeSize write SetAttributeSize;
|
||||
|
||||
property RangeList: TSynEditStorageMem read FRangeList write SetRangeList;
|
||||
end;
|
||||
|
||||
{ TSynEditStringList }
|
||||
@ -144,8 +141,8 @@ type
|
||||
procedure SendNotification(AReason: TSynEditNotifyReason;
|
||||
ASender: TSynEditStrings; aIndex, aCount: Integer); override;
|
||||
|
||||
function GetRange(Index: integer): TSynEditRange; {$IFDEF SYN_LAZARUS}override;{$ENDIF}
|
||||
procedure PutRange(Index: integer; ARange: TSynEditRange); {$IFDEF SYN_LAZARUS}override;{$ENDIF}
|
||||
function GetRange: TSynEditStorageMem; override;
|
||||
procedure PutRange(ARange: TSynEditStorageMem); override;
|
||||
function GetAttribute(const Owner: TClass; const Index: Integer): Pointer; override;
|
||||
procedure SetAttribute(const Owner: TClass; const Index: Integer; const AValue: Pointer); override;
|
||||
function Get(Index: integer): string; override;
|
||||
@ -190,7 +187,6 @@ type
|
||||
public
|
||||
property DosFileFormat: boolean read fDosFileFormat write fDosFileFormat;
|
||||
property LengthOfLongestLine: integer read GetLengthOfLongestLine;
|
||||
property Ranges[Index: integer]: TSynEditRange read GetRange write PutRange;
|
||||
property OnChange: TNotifyEvent read fOnChange write fOnChange;
|
||||
property OnChanging: TNotifyEvent read fOnChanging write fOnChanging;
|
||||
property OnCleared: TNotifyEvent read fOnCleared write fOnCleared;
|
||||
@ -396,7 +392,6 @@ begin
|
||||
FLineChangeNotificationList := TLineRangeNotificationList.Create;
|
||||
inherited Create;
|
||||
SetAttributeSize(0);
|
||||
RegisterAttribute(TSynEditRangeClass, SizeOf(Pointer));
|
||||
RegisterAttribute(TSynEditFlagsClass, SizeOf(TSynEditStringFlag));
|
||||
fDosFileFormat := TRUE;
|
||||
{begin} //mh 2000-10-19
|
||||
@ -445,7 +440,6 @@ begin
|
||||
Strings[Count-1] := AStrings[i];
|
||||
Objects[Count-1] := AStrings.Objects[i];
|
||||
end;
|
||||
SetAttribute(TSynEditRangeClass, Count-1, NullRange);
|
||||
Flags[Count-1] := [];
|
||||
end;
|
||||
FLineRangeNotificationList.CallRangeNotifyEvents(self, FirstAdded, Count - FirstAdded);
|
||||
@ -623,12 +617,9 @@ begin
|
||||
Result := nil;
|
||||
end;
|
||||
|
||||
function TSynEditStringList.GetRange(Index: integer): TSynEditRange;
|
||||
function TSynEditStringList.GetRange: TSynEditStorageMem;
|
||||
begin
|
||||
if (Index >= 0) and (Index < Count) then
|
||||
Result := TSynEditRange(GetAttribute(TSynEditRangeClass, Index))
|
||||
else
|
||||
Result := nil;
|
||||
Result := FList.RangeList;
|
||||
end;
|
||||
|
||||
procedure TSynEditStringList.Grow;
|
||||
@ -670,7 +661,6 @@ begin
|
||||
SetCount(Count + 1);
|
||||
fList[Index] := S;
|
||||
FList.Objects[Index] := nil;
|
||||
Ranges[Index] := NullRange;
|
||||
Flags[Index] := [];
|
||||
EndUpdate;
|
||||
end;
|
||||
@ -739,17 +729,9 @@ begin
|
||||
EndUpdate;
|
||||
end;
|
||||
|
||||
procedure TSynEditStringList.PutRange(Index: integer; ARange: TSynEditRange);
|
||||
procedure TSynEditStringList.PutRange(ARange: TSynEditStorageMem);
|
||||
begin
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
// do not call BeginUpdate/EndUpdate. It would call the too generic OnChange
|
||||
// events
|
||||
SetAttribute(TSynEditRangeClass, Index, Pointer(PtrUInt(ARange)));
|
||||
{$ELSE}
|
||||
BeginUpdate;
|
||||
SetAttribute(TSynEditRangeClass, Index, Pointer(PtrUInt(ARange)));
|
||||
EndUpdate;
|
||||
{$ENDIF}
|
||||
FList.RangeList := ARange;
|
||||
end;
|
||||
|
||||
function TSynEditStringList.GetAttribute(const Owner: TClass; const Index: Integer): Pointer;
|
||||
@ -999,110 +981,111 @@ const
|
||||
constructor TSynEditStringMemory.Create;
|
||||
begin
|
||||
inherited Create;
|
||||
FCapacity := 0;
|
||||
FCount := 0;
|
||||
AttributeSize := 0;
|
||||
end;
|
||||
|
||||
destructor TSynEditStringMemory.Destroy;
|
||||
begin
|
||||
SetCount(0);
|
||||
SetCapacity(0);
|
||||
inherited Destroy;
|
||||
FRangeList := nil;
|
||||
end;
|
||||
|
||||
procedure TSynEditStringMemory.Move(AFrom, ATo, ALen: Integer);
|
||||
var
|
||||
i, len: Integer;
|
||||
Len, i: Integer;
|
||||
begin
|
||||
//debugln(['TSynEditStringMemory.Move(',AFrom, ',', ATo, ', ',ALen,')']);
|
||||
if ATo < AFrom then begin
|
||||
Len := Min(ALen, AFrom-ATo);
|
||||
for i:=ATo to ATo + Len -1 do Strings[i]:='';
|
||||
System.Move((FMem+AFrom*FAttributeSize)^, (FMem+ATo*FAttributeSize)^, Alen*FAttributeSize);
|
||||
FillChar((FMem+(AFrom+ALen-Len)*FAttributeSize)^, Len*FAttributeSize, 0);
|
||||
end else begin
|
||||
Len := Min(ALen, ATo-AFrom);
|
||||
for i:=ATo+Alen-Len to ATo+ALen -1 do Strings[i]:='';
|
||||
System.Move((FMem+AFrom*FAttributeSize)^, (FMem+ATo*FAttributeSize)^, Alen*FAttributeSize);
|
||||
FillChar((FMem+AFrom*FAttributeSize)^, Len*FAttributeSize, 0);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TSynEditStringMemory.GetCapacity: Integer;
|
||||
begin
|
||||
Result := FCapacity;
|
||||
end;
|
||||
|
||||
procedure TSynEditStringMemory.SetCapacity(const AValue: Integer);
|
||||
begin
|
||||
if FCapacity = AValue then exit;;
|
||||
FMem := ReallocMem(FMem, AValue * FAttributeSize);
|
||||
if AValue > FCapacity then
|
||||
FillChar((FMem+FCapacity*FAttributeSize)^, (AValue-FCapacity)*FAttributeSize, 0);
|
||||
FCapacity := AValue;
|
||||
inherited Move(AFrom, ATo, ALen);
|
||||
if assigned(FRangeList) then
|
||||
FRangeList.Move(AFrom, ATo, ALen);
|
||||
end;
|
||||
|
||||
procedure TSynEditStringMemory.SetCount(const AValue: Integer);
|
||||
var
|
||||
i : Integer;
|
||||
begin
|
||||
If FCount = AValue then exit;
|
||||
for i:= AValue to FCount-1 do Strings[i]:='';
|
||||
FCount := AValue;
|
||||
If Count = AValue then exit;
|
||||
for i:= AValue to Count-1 do Strings[i]:='';
|
||||
inherited SetCount(AValue);
|
||||
if assigned(FRangeList) then
|
||||
FRangeList.Count := AValue;
|
||||
end;
|
||||
|
||||
|
||||
function TSynEditStringMemory.GetAttributeSize: Integer;
|
||||
begin
|
||||
Result := FAttributeSize - SizeOf(String) - SizeOf(TObject)
|
||||
end;
|
||||
|
||||
procedure TSynEditStringMemory.SetAttributeSize(const AValue: Integer);
|
||||
var
|
||||
c: LongInt;
|
||||
begin
|
||||
if FAttributeSize = AValue + SizeOf(String) + SizeOf(TObject) then exit;;
|
||||
c := Capacity;
|
||||
Capacity := 0;
|
||||
FAttributeSize := AValue + SizeOf(String) + SizeOf(TObject);
|
||||
SetCapacity(FCapacity);
|
||||
// Todo: Move existing records
|
||||
Capacity := c;
|
||||
end;
|
||||
|
||||
function TSynEditStringMemory.GetString(Index: Integer): String;
|
||||
begin
|
||||
Result := (PString(FMem + Index * FAttributeSize))^;
|
||||
Result := (PString(Mem + Index * FAttributeSize))^;
|
||||
end;
|
||||
|
||||
procedure TSynEditStringMemory.SetString(Index: Integer; const AValue: String);
|
||||
begin
|
||||
(PString(FMem + Index * FAttributeSize))^ := AValue;
|
||||
(PString(Mem + Index * FAttributeSize))^ := AValue;
|
||||
end;
|
||||
|
||||
function TSynEditStringMemory.ItemSize: Integer;
|
||||
begin
|
||||
Result := FAttributeSize;
|
||||
end;
|
||||
|
||||
procedure TSynEditStringMemory.SetCapacity(const AValue: Integer);
|
||||
begin
|
||||
inherited SetCapacity(AValue);
|
||||
if assigned(FRangeList) then
|
||||
FRangeList.Capacity := AValue;
|
||||
end;
|
||||
|
||||
function TSynEditStringMemory.GetObject(Index: Integer): TObject;
|
||||
begin
|
||||
Result := (PObject(FMem + Index * FAttributeSize + SizeOf(String)))^;
|
||||
Result := (PObject(Mem + Index * FAttributeSize + SizeOf(String)))^;
|
||||
end;
|
||||
|
||||
procedure TSynEditStringMemory.SetObject(Index: Integer; const AValue: TObject);
|
||||
begin
|
||||
(PObject(FMem + Index * FAttributeSize + SizeOf(String)))^ := AValue;
|
||||
(PObject(Mem + Index * FAttributeSize + SizeOf(String)))^ := AValue;
|
||||
end;
|
||||
|
||||
procedure TSynEditStringMemory.SetRangeList(const AValue: TSynEditStorageMem);
|
||||
begin
|
||||
FRangeList := AValue;
|
||||
if FRangeList <> nil then begin
|
||||
FRangeList.Capacity := Capacity;
|
||||
FRangeList.Count := Count;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TSynEditStringMemory.GetAttribute(Index: Integer; Pos: Integer; Size: Word): Pointer;
|
||||
begin
|
||||
case Size of
|
||||
1 : Result := Pointer(PtrUInt((PByte(FMem + Index * FAttributeSize + AttributeOfset + Pos))^));
|
||||
2 : Result := Pointer(PtrUInt((PWord(FMem + Index * FAttributeSize + AttributeOfset + Pos))^));
|
||||
4 : Result := Pointer(PtrUInt((PLongWord(FMem + Index * FAttributeSize + AttributeOfset + Pos))^));
|
||||
8 : Result := Pointer(PtrUInt((PQWord(FMem + Index * FAttributeSize + AttributeOfset + Pos))^));
|
||||
1 : Result := Pointer(PtrUInt((PByte(Mem + Index * FAttributeSize + AttributeOfset + Pos))^));
|
||||
2 : Result := Pointer(PtrUInt((PWord(Mem + Index * FAttributeSize + AttributeOfset + Pos))^));
|
||||
4 : Result := Pointer(PtrUInt((PLongWord(Mem + Index * FAttributeSize + AttributeOfset + Pos))^));
|
||||
8 : Result := Pointer(PtrUInt((PQWord(Mem + Index * FAttributeSize + AttributeOfset + Pos))^));
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TSynEditStringMemory.SetAttribute(Index: Integer; Pos: Integer; Size: Word; const AValue: Pointer);
|
||||
begin
|
||||
case Size of
|
||||
1 : (PByte(FMem + Index * FAttributeSize + AttributeOfset + Pos))^ := Byte(PtrUInt(AValue));
|
||||
2 : (PWord(FMem + Index * FAttributeSize + AttributeOfset + Pos))^ := Word(PtrUInt(AValue));
|
||||
4 : (PLongWord(FMem + Index * FAttributeSize + AttributeOfset + Pos))^ := LongWord(PtrUInt(AValue));
|
||||
8 : (PQWord(FMem + Index * FAttributeSize + AttributeOfset + Pos))^ := QWord(PtrUInt(AValue));
|
||||
1 : (PByte(Mem + Index * FAttributeSize + AttributeOfset + Pos))^ := Byte(PtrUInt(AValue));
|
||||
2 : (PWord(Mem + Index * FAttributeSize + AttributeOfset + Pos))^ := Word(PtrUInt(AValue));
|
||||
4 : (PLongWord(Mem + Index * FAttributeSize + AttributeOfset + Pos))^ := LongWord(PtrUInt(AValue));
|
||||
8 : (PQWord(Mem + Index * FAttributeSize + AttributeOfset + Pos))^ := QWord(PtrUInt(AValue));
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -100,7 +100,9 @@ type
|
||||
cfbtUnitSection,
|
||||
cfbtProgram,
|
||||
cfbtUnit,
|
||||
cfbtRecord
|
||||
cfbtRecord,
|
||||
cfbtExcept,
|
||||
cfbtRepeat
|
||||
);
|
||||
TPascalWordTrippletRanges = set of TPascalCodeFoldBlockType;
|
||||
|
||||
@ -108,7 +110,9 @@ const
|
||||
CountPascalCodeFoldBlockOffset: Pointer =
|
||||
Pointer(PtrInt(Integer(high(TPascalCodeFoldBlockType))+1));
|
||||
PascalWordTrippletRanges: TPascalWordTrippletRanges =
|
||||
[cfbtBeginEnd, cfbtProcedure, cfbtClass, cfbtProgram, cfbtRecord];
|
||||
[cfbtBeginEnd, cfbtProcedure, cfbtClass, cfbtProgram, cfbtRecord,
|
||||
cfbtExcept, cfbtRepeat
|
||||
];
|
||||
|
||||
type
|
||||
|
||||
@ -128,24 +132,27 @@ type
|
||||
FMode: TPascalCompilerMode;
|
||||
FBracketNestLevel : Integer;
|
||||
FLastLineCodeFoldLevelFix: integer;
|
||||
FMinimumCodeFoldBlockLevel: Integer;
|
||||
FPasFoldEndLevel: Smallint;
|
||||
FPasFoldFixLevel: Smallint;
|
||||
FPasFoldMinLevel: Smallint;
|
||||
public
|
||||
procedure Clear; override;
|
||||
function Compare(Range: TSynCustomHighlighterRange): integer; override;
|
||||
procedure Assign(Src: TSynCustomHighlighterRange); override;
|
||||
function Add(ABlockType: Pointer = nil; IncreaseLevel: Boolean = True):
|
||||
TSynCustomCodeFoldBlock; override;
|
||||
procedure Pop(DecreaseLevel: Boolean = True); override;
|
||||
procedure IncBracketNestLevel;
|
||||
procedure DecBracketNestLevel;
|
||||
procedure DecLastLineCodeFoldLevelFix;
|
||||
procedure DecLastLinePasFoldFix;
|
||||
property Mode: TPascalCompilerMode read FMode write FMode;
|
||||
property BracketNestLevel: integer read FBracketNestLevel write FBracketNestLevel;
|
||||
// Refers To LastLine while scanning
|
||||
// stored as begining of the next line, it will refer to 2nd last line
|
||||
property LastLineCodeFoldLevelFix: integer
|
||||
read FLastLineCodeFoldLevelFix write FLastLineCodeFoldLevelFix;
|
||||
// Refers To this line while scanning
|
||||
// stored as begining of the next line, it will refer to the last line
|
||||
property MinimumCodeFoldBlockLevel: integer
|
||||
read FMinimumCodeFoldBlockLevel write FMinimumCodeFoldBlockLevel;
|
||||
property PasFoldEndLevel: Smallint read FPasFoldEndLevel write FPasFoldEndLevel;
|
||||
property PasFoldFixLevel: Smallint read FPasFoldFixLevel write FPasFoldFixLevel;
|
||||
property PasFoldMinLevel: Smallint read FPasFoldMinLevel write FPasFoldMinLevel;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
@ -161,6 +168,7 @@ type
|
||||
fAsmStart: Boolean;
|
||||
FNestedComments: boolean;
|
||||
FStartCodeFoldBlockLevel: integer;
|
||||
FPasStartLevel: Smallint;
|
||||
fRange: TRangeStates;
|
||||
FAtLineStart: Boolean; // Line had only spaces or comments sofar
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
@ -332,18 +340,27 @@ type
|
||||
protected
|
||||
function GetFoldNodeInfo(Line, Index: Integer): TSynFoldNodeInfo; override;
|
||||
function GetFoldNodeInfoCount(Line: Integer): Integer; override;
|
||||
|
||||
function GetIdentChars: TSynIdentChars; override;
|
||||
function IsFilterStored: boolean; override; //mh 2000-10-08
|
||||
|
||||
procedure CreateRootCodeFoldBlock; override;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
function StartPascalCodeFoldBlock(ABlockType: TPascalCodeFoldBlockType;
|
||||
SubBlock: boolean = false): TSynCustomCodeFoldBlock;
|
||||
procedure EndCodeFoldBlock(DecreaseLevel: Boolean = True); override;
|
||||
procedure CloseBeginEndBlocks;
|
||||
function GetRangeClass: TSynCustomHighlighterRangeClass; override;
|
||||
{$ENDIF}
|
||||
procedure EndCodeFoldBlockLastLine;
|
||||
function TopPascalCodeFoldBlockType: TPascalCodeFoldBlockType;
|
||||
|
||||
function GetRangeClass: TSynCustomHighlighterRangeClass; override;
|
||||
property PasCodeFoldRange: TSynPasSynRange read GetPasCodeFoldRange;
|
||||
|
||||
function MinimumPasFoldLevel(Index: Integer): integer;
|
||||
function EndPasFoldLevel(Index: Integer): integer;
|
||||
function LastLinePasFoldLevelFix(Index: Integer): integer;
|
||||
|
||||
function LastLineFoldLevelFix(Index: Integer): integer;
|
||||
function GetDrawDivider(Index: integer): Boolean; override;
|
||||
public
|
||||
{$IFNDEF SYN_CPPB_1} class {$ENDIF}
|
||||
function GetCapabilities: TSynHighlighterCapabilities; override;
|
||||
@ -374,15 +391,14 @@ type
|
||||
function UseUserSettings(settingIndex: integer): boolean; override;
|
||||
procedure EnumUserSettings(settings: TStrings); override;
|
||||
|
||||
//code fold
|
||||
function LastLineCodeFoldLevelFix: integer; override;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
function TopPascalCodeFoldBlockType: TPascalCodeFoldBlockType;
|
||||
{$ENDIF}
|
||||
// fold-nodes that can be collapsed
|
||||
function FoldOpenCount(ALineIndex: Integer): integer; override;
|
||||
function FoldCloseCount(ALineIndex: Integer): integer; override;
|
||||
function FoldNestCount(ALineIndex: Integer): integer; override;
|
||||
function FoldLineLength(ALineIndex, FoldIndex: Integer): integer; override;
|
||||
|
||||
function MinimumFoldLevel(Index: Integer): integer; override;
|
||||
function EndFoldLevel(Index: Integer): integer; override;
|
||||
function LastLineFoldLevelFix(Index: Integer): integer; override;
|
||||
published
|
||||
property AsmAttri: TSynHighlighterAttributes read fAsmAttri write fAsmAttri;
|
||||
property CommentAttri: TSynHighlighterAttributes read fCommentAttri
|
||||
@ -755,7 +771,7 @@ begin
|
||||
if FCompilerMode=AValue then exit;
|
||||
FCompilerMode:=AValue;
|
||||
FNestedComments:=FCompilerMode in [pcmFPC,pcmObjFPC];
|
||||
TSynPasSynRange(CodeFoldRange).Mode:=FCompilerMode;
|
||||
PasCodeFoldRange.Mode:=FCompilerMode;
|
||||
//DebugLn(['TSynPasSyn.SetCompilerMode FCompilerMode=',ord(FCompilerMode),' FNestedComments=',FNestedComments]);
|
||||
end;
|
||||
|
||||
@ -810,13 +826,17 @@ begin
|
||||
then begin
|
||||
Result := tkKey;
|
||||
fRange := fRange - [rsAsm];
|
||||
TSynPasSynRange(CodeFoldRange).BracketNestLevel := 0; // Reset in case of partial code
|
||||
PasCodeFoldRange.BracketNestLevel := 0; // Reset in case of partial code
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
// there may be more than on block ending here
|
||||
if TopPascalCodeFoldBlockType = cfbtRecord then begin
|
||||
EndCodeFoldBlock;
|
||||
end else if TopPascalCodeFoldBlockType = cfbtUnit then begin
|
||||
EndCodeFoldBlock;
|
||||
end else if TopPascalCodeFoldBlockType = cfbtExcept then begin
|
||||
EndCodeFoldBlock;
|
||||
if TopPascalCodeFoldBlockType = cfbtBeginEnd then
|
||||
EndCodeFoldBlock;
|
||||
end else if TopPascalCodeFoldBlockType = cfbtBeginEnd then begin
|
||||
EndCodeFoldBlock;
|
||||
if TopPascalCodeFoldBlockType = cfbtProcedure then
|
||||
@ -910,7 +930,7 @@ begin
|
||||
// if we are in an include file, we may not know the state
|
||||
if (fRange * [rsImplementation, rsInterface] = []) then
|
||||
Include(fRange, rsImplementation);
|
||||
TSynPasSynRange(CodeFoldRange).BracketNestLevel := 0; // Reset in case of partial code
|
||||
PasCodeFoldRange.BracketNestLevel := 0; // Reset in case of partial code
|
||||
if TopPascalCodeFoldBlockType=cfbtVarType then EndCodeFoldBlockLastLine;
|
||||
Result := tkKey;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
@ -942,7 +962,7 @@ begin
|
||||
if KeyComp('Else') then
|
||||
Result := tkKey
|
||||
else if KeyComp('Var') then begin
|
||||
if (TSynPasSynRange(CodeFoldRange).BracketNestLevel = 0) and
|
||||
if (PasCodeFoldRange.BracketNestLevel = 0) and
|
||||
(TopPascalCodeFoldBlockType in
|
||||
[cfbtVarType, cfbtNone, cfbtProcedure, cfbtProgram, cfbtUnit, cfbtUnitSection]) then begin
|
||||
if TopPascalCodeFoldBlockType=cfbtVarType then EndCodeFoldBlockLastLine;
|
||||
@ -988,7 +1008,7 @@ function TSynPasSyn.Func54: TtkTokenKind;
|
||||
begin
|
||||
if KeyComp('Class') then begin
|
||||
Result := tkKey;
|
||||
if (rsAfterEqual in fRange) and (TSynPasSynRange(CodeFoldRange).BracketNestLevel = 0)
|
||||
if (rsAfterEqual in fRange) and (PasCodeFoldRange.BracketNestLevel = 0)
|
||||
then begin
|
||||
fRange := fRange + [rsAtClass];
|
||||
StartPascalCodeFoldBlock(cfbtClass);
|
||||
@ -1001,7 +1021,7 @@ function TSynPasSyn.Func55: TtkTokenKind;
|
||||
begin
|
||||
if KeyComp('Object') then begin
|
||||
Result := tkKey;
|
||||
if (rsAfterEqual in fRange) and (TSynPasSynRange(CodeFoldRange).BracketNestLevel = 0)
|
||||
if (rsAfterEqual in fRange) and (PasCodeFoldRange.BracketNestLevel = 0)
|
||||
then begin
|
||||
fRange := fRange + [rsAtClass];
|
||||
StartPascalCodeFoldBlock(cfbtClass);
|
||||
@ -1060,15 +1080,11 @@ begin
|
||||
end
|
||||
else if KeyComp('Array') then Result := tkKey
|
||||
else if KeyComp('Try') then
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
begin
|
||||
if TopPascalCodeFoldBlockType=cfbtBeginEnd then
|
||||
StartPascalCodeFoldBlock(cfbtBeginEnd,true);
|
||||
Result := tkKey;
|
||||
end
|
||||
{$ELSE}
|
||||
Result := tkKey
|
||||
{$ENDIF}
|
||||
else if KeyComp('Inline') then Result := tkKey else Result := tkIdentifier;
|
||||
end;
|
||||
|
||||
@ -1091,13 +1107,17 @@ end;
|
||||
|
||||
function TSynPasSyn.Func65: TtkTokenKind;
|
||||
begin
|
||||
if KeyComp('Repeat') then Result := tkKey else Result := tkIdentifier;
|
||||
if KeyComp('Repeat') then begin
|
||||
Result := tkKey;
|
||||
StartPascalCodeFoldBlock(cfbtRepeat, True);
|
||||
end
|
||||
else Result := tkIdentifier;
|
||||
end;
|
||||
|
||||
function TSynPasSyn.Func66: TtkTokenKind;
|
||||
begin
|
||||
if KeyComp('Type') then begin
|
||||
if (TSynPasSynRange(CodeFoldRange).BracketNestLevel = 0)
|
||||
if (PasCodeFoldRange.BracketNestLevel = 0)
|
||||
and (TopPascalCodeFoldBlockType in
|
||||
[cfbtVarType, cfbtNone, cfbtProcedure, cfbtProgram, cfbtUnit, cfbtUnitSection])
|
||||
and not(rsAfterEqual in fRange)
|
||||
@ -1122,7 +1142,7 @@ begin
|
||||
if KeyComp('Stdcall') then
|
||||
Result := tkKey
|
||||
else if KeyComp('Const') then begin
|
||||
if (TSynPasSynRange(CodeFoldRange).BracketNestLevel = 0) and
|
||||
if (PasCodeFoldRange.BracketNestLevel = 0) and
|
||||
(TopPascalCodeFoldBlockType in
|
||||
[cfbtVarType, cfbtNone, cfbtProcedure, cfbtProgram, cfbtUnit, cfbtUnitSection]) then begin
|
||||
if TopPascalCodeFoldBlockType=cfbtVarType then EndCodeFoldBlockLastLine;
|
||||
@ -1140,7 +1160,11 @@ end;
|
||||
|
||||
function TSynPasSyn.Func73: TtkTokenKind;
|
||||
begin
|
||||
if KeyComp('Except') then Result := tkKey else Result := tkIdentifier;
|
||||
if KeyComp('Except') then begin
|
||||
Result := tkKey;
|
||||
StartPascalCodeFoldBlock(cfbtExcept, True);
|
||||
end
|
||||
else Result := tkIdentifier;
|
||||
end;
|
||||
|
||||
function TSynPasSyn.Func75: TtkTokenKind;
|
||||
@ -1153,12 +1177,20 @@ end;
|
||||
|
||||
function TSynPasSyn.Func76: TtkTokenKind;
|
||||
begin
|
||||
if KeyComp('Until') then Result := tkKey else Result := tkIdentifier;
|
||||
if KeyComp('Until') then begin
|
||||
Result := tkKey;
|
||||
if TopPascalCodeFoldBlockType = cfbtRepeat then EndCodeFoldBlock;
|
||||
end
|
||||
else Result := tkIdentifier;
|
||||
end;
|
||||
|
||||
function TSynPasSyn.Func79: TtkTokenKind;
|
||||
begin
|
||||
if KeyComp('Finally') then Result := tkKey else Result := tkIdentifier;
|
||||
if KeyComp('Finally') then begin
|
||||
Result := tkKey;
|
||||
StartPascalCodeFoldBlock(cfbtExcept, True);
|
||||
end
|
||||
else Result := tkIdentifier;
|
||||
end;
|
||||
|
||||
function TSynPasSyn.Func81: TtkTokenKind;
|
||||
@ -1308,7 +1340,7 @@ function TSynPasSyn.Func102: TtkTokenKind;
|
||||
begin
|
||||
if KeyComp('Function') then begin
|
||||
if not(rsAfterEqual in fRange) then begin
|
||||
TSynPasSynRange(CodeFoldRange).BracketNestLevel := 0; // Reset in case of partial code
|
||||
PasCodeFoldRange.BracketNestLevel := 0; // Reset in case of partial code
|
||||
CloseBeginEndBlocks;
|
||||
if TopPascalCodeFoldBlockType=cfbtVarType then EndCodeFoldBlockLastLine;
|
||||
if ((rsImplementation in fRange) and
|
||||
@ -1330,7 +1362,7 @@ function TSynPasSyn.Func105: TtkTokenKind;
|
||||
begin
|
||||
if KeyComp('Procedure') then begin
|
||||
if not(rsAfterEqual in fRange) then begin
|
||||
TSynPasSynRange(CodeFoldRange).BracketNestLevel := 0; // Reset in case of partial code
|
||||
PasCodeFoldRange.BracketNestLevel := 0; // Reset in case of partial code
|
||||
CloseBeginEndBlocks;
|
||||
if TopPascalCodeFoldBlockType=cfbtVarType then EndCodeFoldBlockLastLine;
|
||||
if ((rsImplementation in fRange) and
|
||||
@ -1429,7 +1461,7 @@ end;
|
||||
function TSynPasSyn.Func136: TtkTokenKind;
|
||||
begin
|
||||
if KeyComp('Finalization') then begin
|
||||
TSynPasSynRange(CodeFoldRange).BracketNestLevel := 0; // Reset in case of partial code
|
||||
PasCodeFoldRange.BracketNestLevel := 0; // Reset in case of partial code
|
||||
CloseBeginEndBlocks;
|
||||
if TopPascalCodeFoldBlockType=cfbtVarType then EndCodeFoldBlockLastLine;
|
||||
if TopPascalCodeFoldBlockType=cfbtUnitSection then EndCodeFoldBlockLastLine;
|
||||
@ -1454,7 +1486,7 @@ begin
|
||||
begin
|
||||
if not(rsAfterEqual in fRange) then
|
||||
begin
|
||||
TSynPasSynRange(CodeFoldRange).BracketNestLevel := 0; // Reset in case of partial code
|
||||
PasCodeFoldRange.BracketNestLevel := 0; // Reset in case of partial code
|
||||
CloseBeginEndBlocks;
|
||||
if TopPascalCodeFoldBlockType = cfbtVarType then EndCodeFoldBlockLastLine;
|
||||
if ((rsImplementation in fRange) and
|
||||
@ -1474,7 +1506,7 @@ function TSynPasSyn.Func166: TtkTokenKind;
|
||||
begin
|
||||
if KeyComp('Constructor') then begin
|
||||
if not(rsAfterEqual in fRange) then begin
|
||||
TSynPasSynRange(CodeFoldRange).BracketNestLevel := 0; // Reset in case of partial code
|
||||
PasCodeFoldRange.BracketNestLevel := 0; // Reset in case of partial code
|
||||
CloseBeginEndBlocks;
|
||||
if TopPascalCodeFoldBlockType=cfbtVarType then EndCodeFoldBlockLastLine;
|
||||
if ((rsImplementation in fRange) and
|
||||
@ -1485,7 +1517,7 @@ begin
|
||||
Result := tkKey;
|
||||
end else
|
||||
if KeyComp('Implementation') then begin
|
||||
TSynPasSynRange(CodeFoldRange).BracketNestLevel := 0; // Reset in case of partial code
|
||||
PasCodeFoldRange.BracketNestLevel := 0; // Reset in case of partial code
|
||||
CloseBeginEndBlocks;
|
||||
if TopPascalCodeFoldBlockType=cfbtVarType then EndCodeFoldBlockLastLine;
|
||||
if TopPascalCodeFoldBlockType=cfbtUnitSection then EndCodeFoldBlockLastLine;
|
||||
@ -1505,7 +1537,7 @@ end;
|
||||
function TSynPasSyn.Func168: TtkTokenKind;
|
||||
begin
|
||||
if KeyComp('Initialization') then begin
|
||||
TSynPasSynRange(CodeFoldRange).BracketNestLevel := 0; // Reset in case of partial code
|
||||
PasCodeFoldRange.BracketNestLevel := 0; // Reset in case of partial code
|
||||
CloseBeginEndBlocks;
|
||||
if TopPascalCodeFoldBlockType=cfbtVarType then EndCodeFoldBlockLastLine;
|
||||
if TopPascalCodeFoldBlockType=cfbtUnitSection then EndCodeFoldBlockLastLine;
|
||||
@ -1672,18 +1704,17 @@ end; { Create }
|
||||
procedure TSynPasSyn.SetLine(const NewValue: string; LineNumber:Integer);
|
||||
begin
|
||||
//DebugLn(['TSynPasSyn.SetLine START LineNumber=',LineNumber,' Line="',NewValue,'"']);
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
fLineStr := NewValue;
|
||||
fLineLen:=length(fLineStr);
|
||||
fLine:=PChar(Pointer(fLineStr));
|
||||
Run := 0;
|
||||
Inherited SetLine(NewValue,LineNumber);
|
||||
FStartCodeFoldBlockLevel := FMinimumCodeFoldBlockLevel;
|
||||
TSynPasSynRange(CodeFoldRange).LastLineCodeFoldLevelFix := 0;
|
||||
{$ELSE}
|
||||
fLine := PChar(NewValue);
|
||||
Run := 0;
|
||||
{$ENDIF}
|
||||
FStartCodeFoldBlockLevel := MinimumCodeFoldBlockLevel;
|
||||
PasCodeFoldRange.LastLineCodeFoldLevelFix := 0;
|
||||
PasCodeFoldRange.PasFoldFixLevel := 0;
|
||||
PasCodeFoldRange.PasFoldMinLevel :=
|
||||
PasCodeFoldRange.PasFoldEndLevel;
|
||||
FPasStartLevel := PasCodeFoldRange.PasFoldMinLevel;
|
||||
FNodeInfoLine := -1;
|
||||
fLineNumber := LineNumber;
|
||||
FAtLineStart := True;
|
||||
@ -1947,7 +1978,7 @@ begin
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
if Run>=fLineLen then begin
|
||||
fTokenID:=tkSymbol;
|
||||
TSynPasSynRange(CodeFoldRange).IncBracketNestLevel;
|
||||
PasCodeFoldRange.IncBracketNestLevel;
|
||||
exit;
|
||||
end;
|
||||
{$ENDIF}
|
||||
@ -1966,11 +1997,11 @@ begin
|
||||
begin
|
||||
inc(Run);
|
||||
fTokenID := tkSymbol;
|
||||
TSynPasSynRange(CodeFoldRange).IncBracketNestLevel;
|
||||
PasCodeFoldRange.IncBracketNestLevel;
|
||||
end;
|
||||
else
|
||||
fTokenID := tkSymbol;
|
||||
TSynPasSynRange(CodeFoldRange).IncBracketNestLevel;
|
||||
PasCodeFoldRange.IncBracketNestLevel;
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -1978,7 +2009,7 @@ procedure TSynPasSyn.RoundCloseProc;
|
||||
begin
|
||||
inc(Run);
|
||||
fTokenID := tkSymbol;
|
||||
TSynPasSynRange(CodeFoldRange).DecBracketNestLevel;
|
||||
PasCodeFoldRange.DecBracketNestLevel;
|
||||
fRange := fRange + [rsAtClosingBracket];
|
||||
end;
|
||||
|
||||
@ -1986,14 +2017,14 @@ procedure TSynPasSyn.SquareOpenProc;
|
||||
begin
|
||||
inc(Run);
|
||||
fTokenID := tkSymbol;
|
||||
TSynPasSynRange(CodeFoldRange).IncBracketNestLevel;
|
||||
PasCodeFoldRange.IncBracketNestLevel;
|
||||
end;
|
||||
|
||||
procedure TSynPasSyn.SquareCloseProc;
|
||||
begin
|
||||
inc(Run);
|
||||
fTokenID := tkSymbol;
|
||||
TSynPasSynRange(CodeFoldRange).DecBracketNestLevel;
|
||||
PasCodeFoldRange.DecBracketNestLevel;
|
||||
end;
|
||||
|
||||
procedure TSynPasSyn.EqualSignProc;
|
||||
@ -2011,7 +2042,7 @@ begin
|
||||
EndCodeFoldBlock;
|
||||
if (TopPascalCodeFoldBlockType = cfbtClass) and (rsAfterClass in fRange) then
|
||||
EndCodeFoldBlock;
|
||||
if (rsProperty in fRange) and (TSynPasSynRange(CodeFoldRange).BracketNestLevel = 0) then
|
||||
if (rsProperty in fRange) and (PasCodeFoldRange.BracketNestLevel = 0) then
|
||||
fRange := fRange - [rsProperty];
|
||||
end;
|
||||
|
||||
@ -2110,7 +2141,7 @@ begin
|
||||
fRange := fRange + [rsAfterClass] - [rsAtClass];
|
||||
fProcTable[fLine[Run]];
|
||||
if not (FTokenID in [tkSpace, tkComment, tkDirective]) then begin
|
||||
if (TSynPasSynRange(CodeFoldRange).BracketNestLevel = 0) and
|
||||
if (PasCodeFoldRange.BracketNestLevel = 0) and
|
||||
not(rsAtClosingBracket in fRange) then
|
||||
fRange := fRange - [rsAfterClass];
|
||||
fRange := fRange - [rsAfterEqual, rsAtClosingBracket];
|
||||
@ -2214,41 +2245,29 @@ end;
|
||||
|
||||
function TSynPasSyn.GetRange: Pointer;
|
||||
begin
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
// For speed reasons, we work with fRange instead of CodeFoldRange.RangeType
|
||||
// -> update now
|
||||
CodeFoldRange.RangeType:=Pointer(PtrUInt(Integer(fRange)));
|
||||
PasCodeFoldRange.MinimumCodeFoldBlockLevel := MinimumCodeFoldBlockLevel;
|
||||
// return a fixed copy of the current CodeFoldRange instance
|
||||
Result := inherited GetRange;
|
||||
{$ELSE}
|
||||
Result := Pointer(PtrInt(fRange));
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
procedure TSynPasSyn.SetRange(Value: Pointer);
|
||||
begin
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
//DebugLn(['TSynPasSyn.SetRange START']);
|
||||
inherited SetRange(Value);
|
||||
CompilerMode := TSynPasSynRange(CodeFoldRange).Mode;
|
||||
CompilerMode := PasCodeFoldRange.Mode;
|
||||
fRange := TRangeStates(Integer(PtrUInt(CodeFoldRange.RangeType)));
|
||||
{$ELSE}
|
||||
fRange := TRangeStates(PtrUInt(Value));
|
||||
{$ENDIF}
|
||||
FNodeInfoLine := -1;
|
||||
FStartCodeFoldBlockLevel := FMinimumCodeFoldBlockLevel;
|
||||
end;
|
||||
|
||||
procedure TSynPasSyn.ResetRange;
|
||||
begin
|
||||
fRange := [];
|
||||
FStartCodeFoldBlockLevel:=0;
|
||||
FMinimumCodeFoldBlockLevel := 0;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
FPasStartLevel := 0;
|
||||
Inherited ResetRange;
|
||||
CompilerMode:=pcmDelphi;
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
procedure TSynPasSyn.EnumUserSettings(settings: TStrings);
|
||||
@ -2275,7 +2294,6 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
function TSynPasSyn.TopPascalCodeFoldBlockType: TPascalCodeFoldBlockType;
|
||||
var
|
||||
p: Pointer;
|
||||
@ -2286,41 +2304,117 @@ begin
|
||||
Result := TPascalCodeFoldBlockType(PtrUInt(p));
|
||||
end;
|
||||
|
||||
function TSynPasSyn.MinimumFoldLevel(Index: Integer): integer;
|
||||
function TSynPasSyn.FoldOpenCount(ALineIndex: Integer): integer;
|
||||
begin
|
||||
Result := EndPasFoldLevel(ALineIndex) - MinimumPasFoldLevel(ALineIndex);
|
||||
end;
|
||||
|
||||
function TSynPasSyn.FoldCloseCount(ALineIndex: Integer): integer;
|
||||
begin
|
||||
Result := EndPasFoldLevel(ALineIndex - 1) - MinimumPasFoldLevel(ALineIndex);
|
||||
end;
|
||||
|
||||
function TSynPasSyn.FoldNestCount(ALineIndex: Integer): integer;
|
||||
begin
|
||||
Result := EndPasFoldLevel(ALineIndex);
|
||||
end;
|
||||
|
||||
function TSynPasSyn.FoldLineLength(ALineIndex, FoldIndex: Integer): integer;
|
||||
var
|
||||
r: Pointer;
|
||||
i, lvl, cnt : Integer;
|
||||
e, m: Integer;
|
||||
begin
|
||||
cnt := CurrentLines.Count;
|
||||
e := EndPasFoldLevel(ALineIndex);
|
||||
m := MinimumPasFoldLevel(ALineIndex);
|
||||
lvl := Min(m+1+FoldIndex, e);
|
||||
i := ALineIndex + 1;
|
||||
while (i < cnt) and (MinimumPasFoldLevel(i) >= lvl) do inc(i);
|
||||
// check if fold last line of block (not mixed "end begin")
|
||||
// and not lastlinefix
|
||||
if (i < cnt) and (EndPasFoldLevel(i) > MinimumPasFoldLevel(i)) then
|
||||
dec(i);
|
||||
// Amount of lines, that will become invisible (excludes the cfCollapsed line)
|
||||
Result := i - ALineIndex;
|
||||
end;
|
||||
|
||||
function TSynPasSyn.MinimumPasFoldLevel(Index: Integer): integer;
|
||||
var
|
||||
r: TSynPasSynRange;
|
||||
begin
|
||||
if (Index < 0) or (Index >= CurrentLines.Count) then
|
||||
exit(0);
|
||||
r := CurrentLines.Ranges[Index];
|
||||
if (r <> nil) and (r <> NullRange) then
|
||||
Result := TSynPasSynRange(r).MinimumCodeFoldBlockLevel
|
||||
r := TSynPasSynRange(CurrentRanges[Index]);
|
||||
if (r <> nil) and (Pointer(r) <> NullRange) then
|
||||
Result := Min(r.PasFoldEndLevel + LastLinePasFoldLevelFix(Index + 1),
|
||||
r.PasFoldMinLevel)
|
||||
else
|
||||
Result := 0;
|
||||
end;
|
||||
|
||||
function TSynPasSyn.EndPasFoldLevel(Index: Integer): integer;
|
||||
var
|
||||
r: TSynPasSynRange;
|
||||
begin
|
||||
if (Index < 0) or (Index >= CurrentLines.Count) then
|
||||
exit(0);
|
||||
r := TSynPasSynRange(CurrentRanges[Index]);
|
||||
if (r <> nil) and (Pointer(r) <> NullRange) then
|
||||
Result := r.PasFoldEndLevel + LastLinePasFoldLevelFix(Index + 1)
|
||||
else
|
||||
Result := 0;
|
||||
end;
|
||||
|
||||
function TSynPasSyn.LastLinePasFoldLevelFix(Index: Integer): integer;
|
||||
var
|
||||
r: TSynPasSynRange;
|
||||
begin
|
||||
if (Index < 0) or (Index >= CurrentLines.Count) then
|
||||
exit(0);
|
||||
r := TSynPasSynRange(CurrentRanges[Index]);
|
||||
if (r <> nil) and (Pointer(r) <> NullRange) then
|
||||
Result := r.PasFoldFixLevel
|
||||
else
|
||||
Result := 0;
|
||||
end;
|
||||
|
||||
|
||||
function TSynPasSyn.MinimumFoldLevel(Index: Integer): integer;
|
||||
var
|
||||
r: TSynPasSynRange;
|
||||
begin
|
||||
if (Index < 0) or (Index >= CurrentLines.Count) then
|
||||
exit(0);
|
||||
r := TSynPasSynRange(CurrentRanges[Index]);
|
||||
if (r <> nil) and (Pointer(r) <> NullRange) then
|
||||
Result := Min(r.CodeFoldStackSize + LastLineFoldLevelFix(Index + 1),
|
||||
r.MinimumCodeFoldBlockLevel)
|
||||
else
|
||||
Result := 0;
|
||||
end;
|
||||
|
||||
function TSynPasSyn.EndFoldLevel(Index: Integer): integer;
|
||||
var
|
||||
r: Pointer;
|
||||
r: TSynPasSynRange;
|
||||
begin
|
||||
if (Index < 0) or (Index >= CurrentLines.Count) then
|
||||
exit(0);
|
||||
r := CurrentLines.Ranges[Index];
|
||||
if (r <> nil) and (r <> NullRange) then
|
||||
Result := TSynPasSynRange(r).CodeFoldStackSize
|
||||
r := TSynPasSynRange(CurrentRanges[Index]);
|
||||
if (r <> nil) and (Pointer(r) <> NullRange) then
|
||||
Result := r.CodeFoldStackSize + LastLineFoldLevelFix(Index + 1)
|
||||
else
|
||||
Result := 0;
|
||||
end;
|
||||
|
||||
function TSynPasSyn.LastLineFoldLevelFix(Index: Integer): integer;
|
||||
var
|
||||
r: Pointer;
|
||||
r: TSynPasSynRange;
|
||||
begin
|
||||
if (Index < 0) or (Index >= CurrentLines.Count) then
|
||||
exit(0);
|
||||
r := CurrentLines.Ranges[Index];
|
||||
if (r <> nil) and (r <> NullRange) then
|
||||
Result := TSynPasSynRange(r).LastLineCodeFoldLevelFix
|
||||
r := TSynPasSynRange(CurrentRanges[Index]);
|
||||
if (r <> nil) and (Pointer(r) <> NullRange) then
|
||||
Result := r.LastLineCodeFoldLevelFix
|
||||
else
|
||||
Result := 0;
|
||||
end;
|
||||
@ -2347,10 +2441,10 @@ var
|
||||
p: PtrInt;
|
||||
begin
|
||||
p := 0;
|
||||
if FCatchNodeInfo and not SubBlock then begin // exclude subblocks, because they do not increase the foldlevel yet
|
||||
if FCatchNodeInfo then begin // exclude subblocks, because they do not increase the foldlevel yet
|
||||
GrowNodeInfoList;
|
||||
InitNode(FNodeInfoList[FNodeInfoCount], +1, ABlockType);
|
||||
if not SubBlock then
|
||||
// if not SubBlock then
|
||||
include(FNodeInfoList[FNodeInfoCount].FoldAction, sfaOpen);
|
||||
inc(FNodeInfoCount);
|
||||
end;
|
||||
@ -2363,10 +2457,10 @@ end;
|
||||
procedure TSynPasSyn.EndCodeFoldBlock(DecreaseLevel: Boolean);
|
||||
begin
|
||||
DecreaseLevel := TopCodeFoldBlockType < CountPascalCodeFoldBlockOffset;
|
||||
if FCatchNodeInfo and DecreaseLevel then begin // exclude subblocks, because they do not increase the foldlevel yet
|
||||
if FCatchNodeInfo then begin // exclude subblocks, because they do not increase the foldlevel yet
|
||||
GrowNodeInfoList;
|
||||
InitNode(FNodeInfoList[FNodeInfoCount], -1, TopPascalCodeFoldBlockType);
|
||||
if DecreaseLevel then
|
||||
// if DecreaseLevel then
|
||||
include(FNodeInfoList[FNodeInfoCount].FoldAction, sfaClose);
|
||||
inc(FNodeInfoCount);
|
||||
end;
|
||||
@ -2375,9 +2469,9 @@ end;
|
||||
|
||||
procedure TSynPasSyn.CloseBeginEndBlocks;
|
||||
begin
|
||||
if TopPascalCodeFoldBlockType <> cfbtBeginEnd then
|
||||
if not(TopPascalCodeFoldBlockType in [cfbtBeginEnd, cfbtExcept, cfbtRepeat]) then
|
||||
exit;
|
||||
while TopPascalCodeFoldBlockType = cfbtBeginEnd do
|
||||
while TopPascalCodeFoldBlockType in [cfbtBeginEnd, cfbtExcept, cfbtRepeat] do
|
||||
EndCodeFoldBlockLastLine;
|
||||
if TopPascalCodeFoldBlockType = cfbtProcedure then
|
||||
EndCodeFoldBlockLastLine; // This procedure did have a begin/end block, so it must end too
|
||||
@ -2390,13 +2484,19 @@ begin
|
||||
i := FNodeInfoCount;
|
||||
EndCodeFoldBlock;
|
||||
if FAtLineStart then begin
|
||||
// If we are not at linestate, new folds could have been opened => handle as normal close
|
||||
// If we are not at linestart, new folds could have been opened => handle as normal close
|
||||
if (CurrentCodeFoldBlockLevel < FStartCodeFoldBlockLevel) and
|
||||
(FStartCodeFoldBlockLevel > 0)
|
||||
then begin
|
||||
TSynPasSynRange(CodeFoldRange).DecLastLineCodeFoldLevelFix;
|
||||
PasCodeFoldRange.DecLastLineCodeFoldLevelFix;
|
||||
dec(FStartCodeFoldBlockLevel);
|
||||
end
|
||||
end;
|
||||
if (PasCodeFoldRange.PasFoldEndLevel < FPasStartLevel) and
|
||||
(FPasStartLevel > 0)
|
||||
then begin
|
||||
PasCodeFoldRange.DecLastLinePasFoldFix;
|
||||
dec(FPasStartLevel);
|
||||
end;
|
||||
end
|
||||
else if FNodeInfoCount > i then begin
|
||||
exclude(FNodeInfoList[FNodeInfoCount - 1].FoldAction, sfaMarkup); // not markup able
|
||||
@ -2404,6 +2504,13 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function TSynPasSyn.GetDrawDivider(Index: integer): Boolean;
|
||||
begin
|
||||
result := (EndFoldLevel(Index) < DrawDividerLevel) and
|
||||
(EndFoldLevel(Index - 1) >= DrawDividerLevel) and
|
||||
(MinimumFoldLevel(Index) = EndFoldLevel(Index)); // not amixed line
|
||||
end;
|
||||
|
||||
function TSynPasSyn.GetFoldNodeInfo(Line, Index: Integer): TSynFoldNodeInfo;
|
||||
var
|
||||
i: LongInt;
|
||||
@ -2441,13 +2548,6 @@ begin
|
||||
Result:=TSynPasSynRange;
|
||||
end;
|
||||
|
||||
function TSynPasSyn.LastLineCodeFoldLevelFix: integer;
|
||||
begin
|
||||
Result := TSynPasSynRange(CodeFoldRange).LastLineCodeFoldLevelFix;
|
||||
end;
|
||||
|
||||
{$endif}
|
||||
|
||||
function TSynPasSyn.UseUserSettings(settingIndex: integer): boolean;
|
||||
// Possible parameter values:
|
||||
// index into TStrings returned by EnumUserSettings
|
||||
@ -2651,7 +2751,6 @@ begin
|
||||
CompilerMode:=pcmObjFPC;
|
||||
end;
|
||||
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
{ TSynPasSynRange }
|
||||
|
||||
procedure TSynPasSynRange.Clear;
|
||||
@ -2659,7 +2758,9 @@ begin
|
||||
inherited Clear;
|
||||
FBracketNestLevel := 0;
|
||||
FLastLineCodeFoldLevelFix := 0;
|
||||
FMinimumCodeFoldBlockLevel := 0;
|
||||
FPasFoldEndLevel := 0;
|
||||
FPasFoldFixLevel := 0;
|
||||
FPasFoldMinLevel := 0;
|
||||
end;
|
||||
|
||||
function TSynPasSynRange.Compare(Range: TSynCustomHighlighterRange): integer;
|
||||
@ -2671,9 +2772,13 @@ begin
|
||||
if Result<>0 then exit;
|
||||
Result := FBracketNestLevel - TSynPasSynRange(Range).FBracketNestLevel;
|
||||
if Result<>0 then exit;
|
||||
Result := FMinimumCodeFoldBlockLevel - TSynPasSynRange(Range).FMinimumCodeFoldBlockLevel;
|
||||
if Result<>0 then exit;
|
||||
Result := FLastLineCodeFoldLevelFix - TSynPasSynRange(Range).FLastLineCodeFoldLevelFix;
|
||||
if Result<>0 then exit;
|
||||
Result := FPasFoldEndLevel - TSynPasSynRange(Range).FPasFoldEndLevel;
|
||||
if Result<>0 then exit;
|
||||
Result := FPasFoldMinLevel - TSynPasSynRange(Range).FPasFoldMinLevel;
|
||||
if Result<>0 then exit;
|
||||
Result := FPasFoldFixLevel - TSynPasSynRange(Range).FPasFoldFixLevel;
|
||||
end;
|
||||
|
||||
procedure TSynPasSynRange.Assign(Src: TSynCustomHighlighterRange);
|
||||
@ -2682,11 +2787,31 @@ begin
|
||||
inherited Assign(Src);
|
||||
FMode:=TSynPasSynRange(Src).FMode;
|
||||
FBracketNestLevel:=TSynPasSynRange(Src).FBracketNestLevel;
|
||||
FMinimumCodeFoldBlockLevel := TSynPasSynRange(Src).FMinimumCodeFoldBlockLevel;
|
||||
FLastLineCodeFoldLevelFix := TSynPasSynRange(Src).FLastLineCodeFoldLevelFix;
|
||||
FPasFoldEndLevel := TSynPasSynRange(Src).FPasFoldEndLevel;
|
||||
FPasFoldMinLevel := TSynPasSynRange(Src).FPasFoldMinLevel;
|
||||
FPasFoldFixLevel := TSynPasSynRange(Src).FPasFoldFixLevel;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TSynPasSynRange.Add(ABlockType: Pointer; IncreaseLevel: Boolean): TSynCustomCodeFoldBlock;
|
||||
begin
|
||||
if IncreaseLevel then
|
||||
inc(FPasFoldEndLevel);
|
||||
Result := inherited Add(ABlockType, True);
|
||||
end;
|
||||
|
||||
procedure TSynPasSynRange.Pop(DecreaseLevel: Boolean);
|
||||
begin
|
||||
if assigned(Top.Parent) then begin
|
||||
if DecreaseLevel then
|
||||
dec(FPasFoldEndLevel);
|
||||
if FPasFoldMinLevel > FPasFoldEndLevel then
|
||||
FPasFoldMinLevel := FPasFoldEndLevel;
|
||||
end;
|
||||
inherited Pop(True);
|
||||
end;
|
||||
|
||||
procedure TSynPasSynRange.IncBracketNestLevel;
|
||||
begin
|
||||
inc(FBracketNestLevel);
|
||||
@ -2702,7 +2827,10 @@ begin
|
||||
dec(FLastLineCodeFoldLevelFix)
|
||||
end;
|
||||
|
||||
{$ENDIF}
|
||||
procedure TSynPasSynRange.DecLastLinePasFoldFix;
|
||||
begin
|
||||
dec(FPasFoldFixLevel);
|
||||
end;
|
||||
|
||||
initialization
|
||||
MakeIdentTable;
|
||||
|
Loading…
Reference in New Issue
Block a user