mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-05-02 04:03:42 +02:00
SynEdit: Basic folding for LFM
git-svn-id: trunk@22552 -
This commit is contained in:
parent
7b3bf8124d
commit
ca94d30747
@ -6,7 +6,7 @@ interface
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
SysUtils, Classes, Controls, Graphics, Menus, LCLIntf, SynGutterBase, SynEditMiscProcs,
|
SysUtils, Classes, Controls, Graphics, Menus, LCLIntf, SynGutterBase, SynEditMiscProcs,
|
||||||
SynEditFoldedView, SynEditMouseCmds, LCLProc;
|
SynEditFoldedView, SynEditMouseCmds, SynEditHighlighterFoldBase, LCLProc;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
@ -226,6 +226,8 @@ begin
|
|||||||
SetLength(FMenuInf,c);
|
SetLength(FMenuInf,c);
|
||||||
for i := c-1 downto 0 do begin
|
for i := c-1 downto 0 do begin
|
||||||
inf := FFoldView.OpenFoldInfo(line-1, i);
|
inf := FFoldView.OpenFoldInfo(line-1, i);
|
||||||
|
if sfaInvalid in inf.HNode.FoldAction then
|
||||||
|
continue;
|
||||||
FMenuInf[i] := inf;
|
FMenuInf[i] := inf;
|
||||||
if (i < c-1) and (FMenuInf[i+1].LineNum = line) and (inf.LineNum <> line)
|
if (i < c-1) and (FMenuInf[i+1].LineNum = line) and (inf.LineNum <> line)
|
||||||
then begin
|
then begin
|
||||||
|
@ -49,7 +49,7 @@ unit SynHighlighterLFM;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
SysUtils, Classes,
|
SysUtils, Classes, math,
|
||||||
{$IFDEF SYN_CLX}
|
{$IFDEF SYN_CLX}
|
||||||
Qt, QControls, QGraphics,
|
Qt, QControls, QGraphics,
|
||||||
{$ELSE}
|
{$ELSE}
|
||||||
@ -60,7 +60,7 @@ uses
|
|||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
Controls, Graphics,
|
Controls, Graphics,
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
SynEditTypes, SynEditHighlighter;
|
SynEditTextBuffer, SynEditTypes, SynEditHighlighter, SynEditHighlighterFoldBase;
|
||||||
|
|
||||||
type
|
type
|
||||||
TtkTokenKind = (tkComment, tkIdentifier, tkKey, tkNull, tkNumber, tkSpace,
|
TtkTokenKind = (tkComment, tkIdentifier, tkKey, tkNull, tkNumber, tkSpace,
|
||||||
@ -68,10 +68,20 @@ type
|
|||||||
|
|
||||||
TRangeState = (rsANil, rsComment, rsUnKnown);
|
TRangeState = (rsANil, rsComment, rsUnKnown);
|
||||||
|
|
||||||
|
TLfmCodeFoldBlockType = (
|
||||||
|
cfbtLfmNone,
|
||||||
|
cfbtLfmObject, // object, inherited, inline
|
||||||
|
cfbtLfmList, // <>
|
||||||
|
cfbtLfmItem // Item
|
||||||
|
);
|
||||||
|
|
||||||
TProcTableProc = procedure of object;
|
TProcTableProc = procedure of object;
|
||||||
|
|
||||||
type
|
type
|
||||||
TSynLFMSyn = class(TSynCustomHighlighter)
|
|
||||||
|
{ TSynLFMSyn }
|
||||||
|
|
||||||
|
TSynLFMSyn = class(TSynCustomFoldHighlighter)
|
||||||
private
|
private
|
||||||
fRange: TRangeState;
|
fRange: TRangeState;
|
||||||
fLine: PChar;
|
fLine: PChar;
|
||||||
@ -108,6 +118,14 @@ type
|
|||||||
protected
|
protected
|
||||||
function GetIdentChars: TSynIdentChars; override;
|
function GetIdentChars: TSynIdentChars; override;
|
||||||
function GetSampleSource: string; override;
|
function GetSampleSource: string; override;
|
||||||
|
protected
|
||||||
|
// folding
|
||||||
|
procedure CreateRootCodeFoldBlock; override;
|
||||||
|
|
||||||
|
function StartLfmCodeFoldBlock
|
||||||
|
(ABlockType: TLfmCodeFoldBlockType): TSynCustomCodeFoldBlock;
|
||||||
|
procedure EndLfmCodeFoldBlock;
|
||||||
|
function TopLfmCodeFoldBlockType(DownIndex: Integer = 0): TLfmCodeFoldBlockType;
|
||||||
public
|
public
|
||||||
{$IFNDEF SYN_CPPB_1} class {$ENDIF} //mh 2000-07-14
|
{$IFNDEF SYN_CPPB_1} class {$ENDIF} //mh 2000-07-14
|
||||||
function GetLanguageName: string; override;
|
function GetLanguageName: string; override;
|
||||||
@ -131,6 +149,15 @@ type
|
|||||||
procedure SetRange(Value: Pointer); override;
|
procedure SetRange(Value: Pointer); override;
|
||||||
procedure ResetRange; override;
|
procedure ResetRange; override;
|
||||||
property IdentChars;
|
property IdentChars;
|
||||||
|
public
|
||||||
|
// folding
|
||||||
|
function FoldOpenCount(ALineIndex: Integer; AType: Integer = 0): integer; override;
|
||||||
|
function FoldCloseCount(ALineIndex: Integer; AType: Integer = 0): integer; override;
|
||||||
|
function FoldNestCount(ALineIndex: Integer; AType: Integer = 0): integer; override;
|
||||||
|
function FoldLineLength(ALineIndex, FoldIndex: Integer): integer; override;
|
||||||
|
// TODO: make private
|
||||||
|
function MinimumFoldLevel(ALineIndex: Integer): integer; override;
|
||||||
|
function EndFoldLevel(ALineIndex: Integer): integer; override;
|
||||||
published
|
published
|
||||||
property CommentAttri: TSynHighlighterAttributes read fCommentAttri
|
property CommentAttri: TSynHighlighterAttributes read fCommentAttri
|
||||||
write fCommentAttri;
|
write fCommentAttri;
|
||||||
@ -279,6 +306,7 @@ end;
|
|||||||
procedure TSynLFMSyn.SetLine({$IFDEF FPC}const {$ENDIF}NewValue: String;
|
procedure TSynLFMSyn.SetLine({$IFDEF FPC}const {$ENDIF}NewValue: String;
|
||||||
LineNumber: Integer);
|
LineNumber: Integer);
|
||||||
begin
|
begin
|
||||||
|
inherited;
|
||||||
fLine := PChar(NewValue);
|
fLine := PChar(NewValue);
|
||||||
Run := 0;
|
Run := 0;
|
||||||
fLineNumber := LineNumber;
|
fLineNumber := LineNumber;
|
||||||
@ -340,6 +368,8 @@ begin
|
|||||||
(fLine[Run + 2] in ['d', 'D']) and
|
(fLine[Run + 2] in ['d', 'D']) and
|
||||||
not (fLine[Run + 3] in ['_', '0'..'9', 'a'..'z', 'A'..'Z'])
|
not (fLine[Run + 3] in ['_', '0'..'9', 'a'..'z', 'A'..'Z'])
|
||||||
then begin
|
then begin
|
||||||
|
if (TopLfmCodeFoldBlockType in [cfbtLfmObject, cfbtLfmItem]) then
|
||||||
|
EndLfmCodeFoldBlock;
|
||||||
fTokenID := tkKey;
|
fTokenID := tkKey;
|
||||||
Inc(Run, 3);
|
Inc(Run, 3);
|
||||||
end else
|
end else
|
||||||
@ -387,6 +417,7 @@ begin
|
|||||||
not (fLine[Run + 6] in ['_', '0'..'9', 'a'..'z', 'A'..'Z'])
|
not (fLine[Run + 6] in ['_', '0'..'9', 'a'..'z', 'A'..'Z'])
|
||||||
then
|
then
|
||||||
begin
|
begin
|
||||||
|
StartLfmCodeFoldBlock(cfbtLfmObject);
|
||||||
fTokenID := tkKey;
|
fTokenID := tkKey;
|
||||||
Inc(Run, 6);
|
Inc(Run, 6);
|
||||||
end
|
end
|
||||||
@ -407,6 +438,7 @@ begin
|
|||||||
not (fLine[Run + 9] in ['_', '0'..'9', 'a'..'z', 'A'..'Z']))
|
not (fLine[Run + 9] in ['_', '0'..'9', 'a'..'z', 'A'..'Z']))
|
||||||
then
|
then
|
||||||
begin
|
begin
|
||||||
|
StartLfmCodeFoldBlock(cfbtLfmObject);
|
||||||
fTokenID := tkKey;
|
fTokenID := tkKey;
|
||||||
Inc(Run, 9);
|
Inc(Run, 9);
|
||||||
end
|
end
|
||||||
@ -418,9 +450,20 @@ begin
|
|||||||
not (fLine[Run + 6] in ['_', '0'..'9', 'a'..'z', 'A'..'Z']))
|
not (fLine[Run + 6] in ['_', '0'..'9', 'a'..'z', 'A'..'Z']))
|
||||||
then
|
then
|
||||||
begin
|
begin
|
||||||
|
StartLfmCodeFoldBlock(cfbtLfmObject);
|
||||||
fTokenID := tkKey;
|
fTokenID := tkKey;
|
||||||
Inc(Run, 6);
|
Inc(Run, 6);
|
||||||
end
|
end
|
||||||
|
else if ((fLine[Run + 1] in ['t', 'T']) and
|
||||||
|
(fLine[Run + 2] in ['e', 'E']) and
|
||||||
|
(fLine[Run + 3] in ['m', 'M']) and
|
||||||
|
not (fLine[Run + 4] in ['_', '0'..'9', 'a'..'z', 'A'..'Z']))
|
||||||
|
then
|
||||||
|
begin
|
||||||
|
StartLfmCodeFoldBlock(cfbtLfmItem);
|
||||||
|
fTokenID := tkIdentifier;
|
||||||
|
Inc(Run, 4);
|
||||||
|
end
|
||||||
else
|
else
|
||||||
AltProc;
|
AltProc;
|
||||||
end;
|
end;
|
||||||
@ -447,6 +490,11 @@ end;
|
|||||||
|
|
||||||
procedure TSynLFMSyn.SymbolProc;
|
procedure TSynLFMSyn.SymbolProc;
|
||||||
begin
|
begin
|
||||||
|
if fLine[Run] = '<' then
|
||||||
|
StartLfmCodeFoldBlock(cfbtLfmList);
|
||||||
|
if (fLine[Run] = '>') and (TopLfmCodeFoldBlockType = cfbtLfmList) then
|
||||||
|
EndLfmCodeFoldBlock;
|
||||||
|
|
||||||
inc(Run);
|
inc(Run);
|
||||||
fTokenID := tkSymbol;
|
fTokenID := tkSymbol;
|
||||||
end;
|
end;
|
||||||
@ -497,7 +545,8 @@ end;
|
|||||||
|
|
||||||
function TSynLFMSyn.GetRange: Pointer;
|
function TSynLFMSyn.GetRange: Pointer;
|
||||||
begin
|
begin
|
||||||
Result := Pointer(PtrInt(fRange));
|
CodeFoldRange.RangeType:=Pointer(PtrUInt(Integer(fRange)));
|
||||||
|
Result := inherited;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TSynLFMSyn.GetTokenID: TtkTokenKind;
|
function TSynLFMSyn.GetTokenID: TtkTokenKind;
|
||||||
@ -553,9 +602,73 @@ begin
|
|||||||
fRange := rsUnknown;
|
fRange := rsUnknown;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TSynLFMSyn.FoldOpenCount(ALineIndex: Integer; AType: Integer): integer;
|
||||||
|
begin
|
||||||
|
Result := EndFoldLevel(ALineIndex) - MinimumFoldLevel(ALineIndex);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSynLFMSyn.FoldCloseCount(ALineIndex: Integer; AType: Integer): integer;
|
||||||
|
begin
|
||||||
|
Result := MinimumFoldLevel(ALineIndex) - EndFoldLevel(ALineIndex - 1);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSynLFMSyn.FoldNestCount(ALineIndex: Integer; AType: Integer): integer;
|
||||||
|
var
|
||||||
|
r: TSynCustomHighlighterRange;
|
||||||
|
begin
|
||||||
|
Result := EndFoldLevel(ALineIndex);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSynLFMSyn.FoldLineLength(ALineIndex, FoldIndex: Integer): integer;
|
||||||
|
var
|
||||||
|
i, lvl, cnt: Integer;
|
||||||
|
e, m: Integer;
|
||||||
|
begin
|
||||||
|
//atype := FoldTypeAtNodeIndex(ALineIndex, FoldIndex);
|
||||||
|
cnt := CurrentLines.Count;
|
||||||
|
e := EndFoldLevel(ALineIndex);
|
||||||
|
m := MinimumFoldLevel(ALineIndex);
|
||||||
|
lvl := Min(m+1+FoldIndex, e);
|
||||||
|
i := ALineIndex + 1;
|
||||||
|
while (i < cnt) and (MinimumFoldLevel(i) >= lvl) do inc(i);
|
||||||
|
// check if fold last line of block (not mixed "end begin")
|
||||||
|
// and not lastlinefix
|
||||||
|
if (i = cnt) or (EndFoldLevel(i) > MinimumFoldLevel(i)) then
|
||||||
|
dec(i);
|
||||||
|
// Amount of lines, that will become invisible (excludes the cfCollapsed line)
|
||||||
|
Result := i - ALineIndex;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSynLFMSyn.MinimumFoldLevel(ALineIndex: Integer): integer;
|
||||||
|
var
|
||||||
|
r: TSynCustomHighlighterRange;
|
||||||
|
begin
|
||||||
|
if (ALineIndex < 0) or (ALineIndex >= CurrentLines.Count) then
|
||||||
|
exit(0);
|
||||||
|
r := TSynCustomHighlighterRange(CurrentRanges[ALineIndex]);
|
||||||
|
if (r <> nil) and (Pointer(r) <> NullRange) then
|
||||||
|
Result := r.MinimumCodeFoldBlockLevel
|
||||||
|
else
|
||||||
|
Result := 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSynLFMSyn.EndFoldLevel(ALineIndex: Integer): integer;
|
||||||
|
var
|
||||||
|
r: TSynCustomHighlighterRange;
|
||||||
|
begin
|
||||||
|
if (ALineIndex < 0) or (ALineIndex >= CurrentLines.Count) then
|
||||||
|
exit(0);
|
||||||
|
r := TSynCustomHighlighterRange(CurrentRanges[ALineIndex]);
|
||||||
|
if (r <> nil) and (Pointer(r) <> NullRange) then
|
||||||
|
Result := r.CodeFoldStackSize
|
||||||
|
else
|
||||||
|
Result := 0;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TSynLFMSyn.SetRange(Value: Pointer);
|
procedure TSynLFMSyn.SetRange(Value: Pointer);
|
||||||
begin
|
begin
|
||||||
fRange := TRangeState(PtrUInt(Value));
|
inherited;
|
||||||
|
fRange := TRangeState(Integer(PtrUInt(CodeFoldRange.RangeType)));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TSynLFMSyn.GetIdentChars: TSynIdentChars;
|
function TSynLFMSyn.GetIdentChars: TSynIdentChars;
|
||||||
@ -579,6 +692,27 @@ begin
|
|||||||
'end';
|
'end';
|
||||||
end; { GetSampleSource }
|
end; { GetSampleSource }
|
||||||
|
|
||||||
|
procedure TSynLFMSyn.CreateRootCodeFoldBlock;
|
||||||
|
begin
|
||||||
|
inherited CreateRootCodeFoldBlock;
|
||||||
|
RootCodeFoldBlock.InitRootBlockType(Pointer(PtrInt(cfbtLfmNone)));
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSynLFMSyn.StartLfmCodeFoldBlock(ABlockType: TLfmCodeFoldBlockType): TSynCustomCodeFoldBlock;
|
||||||
|
begin
|
||||||
|
StartCodeFoldBlock(Pointer(PtrInt(ABlockType)));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSynLFMSyn.EndLfmCodeFoldBlock;
|
||||||
|
begin
|
||||||
|
EndCodeFoldBlock();
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSynLFMSyn.TopLfmCodeFoldBlockType(DownIndex: Integer): TLfmCodeFoldBlockType;
|
||||||
|
begin
|
||||||
|
Result := TLfmCodeFoldBlockType(PtrUInt(TopCodeFoldBlockType(DownIndex)));
|
||||||
|
end;
|
||||||
|
|
||||||
{$IFNDEF SYN_CPPB_1} //mh 2000-07-14
|
{$IFNDEF SYN_CPPB_1} //mh 2000-07-14
|
||||||
initialization
|
initialization
|
||||||
RegisterPlaceableHighlighter(TSynLFMSyn);
|
RegisterPlaceableHighlighter(TSynLFMSyn);
|
||||||
|
Loading…
Reference in New Issue
Block a user