mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-05-02 09:43:42 +02:00
SynEdit Folding: Improved block detection for Pop-up-Menu on fold-gutter
git-svn-id: trunk@19511 -
This commit is contained in:
parent
dcc7ce6884
commit
59d3bbd7e9
@ -173,7 +173,7 @@ type
|
||||
TFoldViewNodeInfo = record
|
||||
HNode: TSynFoldNodeInfo;
|
||||
Text, Keyword: String;
|
||||
LineNum, ColIndex, OpenIndex: Integer;
|
||||
LineNum, ColIndex: Integer;
|
||||
OpenCount: Integer;
|
||||
Folded: boolean;
|
||||
end;
|
||||
@ -2170,36 +2170,72 @@ end;
|
||||
function TSynEditFoldedView.OpenFoldInfo(aStartIndex, ColIndex: Integer): TFoldViewNodeInfo;
|
||||
var
|
||||
hl: TSynCustomFoldHighlighter;
|
||||
n, o: Integer;
|
||||
TypeCnt, Lvl: Integer;
|
||||
EndLvl, CurLvl: Array of integer;
|
||||
i, t, n, o: Integer;
|
||||
nd: TSynFoldNodeInfo;
|
||||
procedure GetEndLvl(l: Integer);
|
||||
var i: integer;
|
||||
begin
|
||||
for i := 1 to TypeCnt do begin
|
||||
EndLvl[i] := hl.FoldNestCount(l-1, i);
|
||||
EndLvl[i] := EndLvl[i] + hl.FoldOpenCount(l, i);
|
||||
CurLvl[i] := EndLvl[i];
|
||||
end
|
||||
end;
|
||||
begin
|
||||
if not(assigned(FHighLighter) and (FHighLighter is TSynCustomFoldHighlighter))
|
||||
then exit;
|
||||
hl := TSynCustomFoldHighlighter(FHighLighter);
|
||||
hl.CurrentLines := fLines;
|
||||
n := hl.FoldNestCount(AStartIndex-1);
|
||||
while (ColIndex < n) do begin
|
||||
TypeCnt := hl.FoldTypeCount;
|
||||
|
||||
Lvl := hl.FoldNestCount(AStartIndex-1);
|
||||
i := 0;
|
||||
if ColIndex >= Lvl then begin
|
||||
// search current line
|
||||
Lvl := Lvl + hl.FoldOpenCount(aStartIndex);
|
||||
i := 1;
|
||||
end;
|
||||
SetLength(EndLvl, TypeCnt+1);
|
||||
SetLength(CurLvl, TypeCnt+1);
|
||||
GetEndLvl(aStartIndex);
|
||||
GetEndLvl(aStartIndex);
|
||||
aStartIndex := aStartIndex + i;
|
||||
while (ColIndex < Lvl) and (aStartIndex > 0) do begin
|
||||
dec(aStartIndex);
|
||||
n := hl.FoldNestCount(AStartIndex-1);
|
||||
end;
|
||||
ColIndex := ColIndex - n;
|
||||
if (hl.FoldOpenCount(aStartIndex) > 0) or
|
||||
(hl.FoldCloseCount(aStartIndex) > 0) then begin
|
||||
o := hl.FoldOpenCount(AStartIndex);
|
||||
Result.OpenCount := o;
|
||||
n := hl.FoldNodeInfoCount[aStartIndex] - 1;
|
||||
while (o > ColIndex) and (n >= 0) do begin
|
||||
nd := hl.FoldNodeInfo[aStartIndex, n];
|
||||
if sfaInvalid in nd.FoldAction then break;
|
||||
if sfaClose in nd.FoldAction then inc(o);
|
||||
if sfaOpen in nd.FoldAction then dec(o);
|
||||
n := o;
|
||||
for i := hl.FoldNodeInfoCount[aStartIndex] - 1 downto 0 do begin
|
||||
nd := hl.FoldNodeInfo[aStartIndex, i];
|
||||
t := nd.FoldGroup;
|
||||
if sfaOpen in nd.FoldAction then begin
|
||||
dec(n);
|
||||
dec(CurLvl[t]);
|
||||
if CurLvl[t] < EndLvl[t] then begin
|
||||
dec(EndLvl[t]);
|
||||
dec(Lvl);
|
||||
if ColIndex = Lvl then begin
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
end else
|
||||
if sfaClose in nd.FoldAction then begin
|
||||
inc(CurLvl[t]);
|
||||
end;
|
||||
end;
|
||||
end
|
||||
else
|
||||
if hl.FoldNestCount(AStartIndex-1) = 0 then break;
|
||||
end;
|
||||
inc(n);
|
||||
Result.HNode := nd;
|
||||
Result.OpenCount := o;
|
||||
Result.Text := fLines[aStartIndex];
|
||||
Result.Keyword := copy(Result.Text, 1 + nd.LogXStart, nd.LogXEnd-nd.LogXStart);
|
||||
Result.LineNum := aStartIndex + 1;
|
||||
Result.ColIndex := ColIndex; // for FoldAction
|
||||
Result.OpenIndex := ColIndex; // for (2/3)
|
||||
Result.ColIndex := n;
|
||||
Result.Folded := IsFoldedAtTextIndex(aStartIndex, ColIndex);
|
||||
end;
|
||||
|
||||
|
@ -110,6 +110,7 @@ type
|
||||
FoldLvlStart, FoldLvlEnd: Integer;
|
||||
FoldAction: TSynFoldActions;
|
||||
FoldType: Pointer;
|
||||
FoldGroup: Integer;
|
||||
end;
|
||||
|
||||
{ TSynCustomFoldHighlighter }
|
||||
@ -152,6 +153,7 @@ type
|
||||
function FoldOpenCount(ALineIndex: Integer; AType: Integer = 0): integer; virtual;
|
||||
function FoldCloseCount(ALineIndex: Integer; AType: Integer = 0): integer; virtual;
|
||||
function FoldNestCount(ALineIndex: Integer; AType: Integer = 0): integer; virtual;
|
||||
function FoldTypeCount: integer; virtual;
|
||||
function FoldTypeAtNodeIndex(ALineIndex, FoldIndex: Integer;
|
||||
UseCloseNodes: boolean = false): integer; virtual;
|
||||
function FoldLineLength(ALineIndex, FoldIndex: Integer): integer; virtual;
|
||||
@ -317,6 +319,11 @@ begin
|
||||
Result := 0;
|
||||
end;
|
||||
|
||||
function TSynCustomFoldHighlighter.FoldTypeCount: integer;
|
||||
begin
|
||||
Result := 1;
|
||||
end;
|
||||
|
||||
function TSynCustomFoldHighlighter.FoldTypeAtNodeIndex(ALineIndex, FoldIndex: Integer;
|
||||
UseCloseNodes: boolean): integer;
|
||||
begin
|
||||
|
@ -203,7 +203,7 @@ begin
|
||||
s := s + copy(inf.Text, inf.HNode.LogXStart, 30 + (30 - length(s)));
|
||||
s2 := '';
|
||||
if inf.OpenCount > 1 then
|
||||
s2 := format(' (%d/%d)', [inf.OpenIndex+1, inf.OpenCount]);
|
||||
s2 := format(' (%d/%d)', [inf.ColIndex+1, inf.OpenCount]);
|
||||
m := TMenuItem.Create(FPopUp);
|
||||
m.Caption := format('%4d %-12s %s', [ inf.LineNum, inf.Keyword+s2+':', s]);
|
||||
m.ShowAlwaysCheckable := true;
|
||||
|
@ -472,6 +472,7 @@ type
|
||||
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 FoldTypeCount: integer; override;
|
||||
function FoldTypeAtNodeIndex(ALineIndex, FoldIndex: Integer;
|
||||
UseCloseNodes: boolean = false): integer; override;
|
||||
function FoldLineLength(ALineIndex, FoldIndex: Integer): integer; override;
|
||||
@ -1890,6 +1891,7 @@ begin
|
||||
end;
|
||||
'{':
|
||||
if NestedComments then begin
|
||||
fStringLen := 1;
|
||||
StartPascalCodeFoldBlock(cfbtNestedComment);
|
||||
end;
|
||||
end;
|
||||
@ -1949,9 +1951,11 @@ begin
|
||||
break;
|
||||
end;
|
||||
'{':
|
||||
if NestedComments then
|
||||
if NestedComments then begin
|
||||
fStringLen := 1;
|
||||
StartPascalCodeFoldBlock(cfbtNestedComment);
|
||||
end;
|
||||
end;
|
||||
Inc(Run);
|
||||
until (Run>=fLineLen);
|
||||
//DebugLn(['TSynPasSyn.DirectiveProc Run=',Run,' fTokenPos=',fTokenPos,' fLineStr=',fLineStr,' Token=',GetToken]);
|
||||
@ -2104,8 +2108,9 @@ begin
|
||||
else if NestedComments
|
||||
and (fLine[Run] = '(') and (fLine[Run + 1] = '*') then
|
||||
begin
|
||||
Inc(Run,2);
|
||||
fStringLen := 2;
|
||||
StartPascalCodeFoldBlock(cfbtNestedComment);
|
||||
Inc(Run,2);
|
||||
end else
|
||||
Inc(Run);
|
||||
until (Run>=fLineLen) or (fLine[Run] in [#0, #10, #13]);
|
||||
@ -2490,6 +2495,7 @@ end;
|
||||
function TSynPasSyn.FoldCloseCount(ALineIndex: Integer; AType: Integer = 0): integer;
|
||||
var
|
||||
inf, inf2: TSynPasRangeInfo;
|
||||
r: TSynPasSynRange;
|
||||
begin
|
||||
Result := 0;
|
||||
if (AType <> 1) then begin
|
||||
@ -2497,7 +2503,8 @@ begin
|
||||
inf2 := TSynHighlighterPasRangeList(CurrentRanges).PasRangeInfo[ALineIndex - 1];
|
||||
end;
|
||||
if (AType = 0) or (AType = 1) then
|
||||
Result := EndPasFoldLevel(ALineIndex - 1) - MinimumPasFoldLevel(ALineIndex);
|
||||
Result := EndPasFoldLevel(ALineIndex - 1)
|
||||
- min(MinimumPasFoldLevel(ALineIndex), EndPasFoldLevel(ALineIndex));
|
||||
if (AType = 0) or (AType = 2) then
|
||||
Result := Result + inf2.EndLevelRegion - inf.MinLevelRegion;
|
||||
if (AType = 0) or (AType = 3) then
|
||||
@ -2519,6 +2526,11 @@ begin
|
||||
Result := Result + inf.EndLevelIfDef;
|
||||
end;
|
||||
|
||||
function TSynPasSyn.FoldTypeCount: integer;
|
||||
begin
|
||||
Result := 3;
|
||||
end;
|
||||
|
||||
function TSynPasSyn.FoldTypeAtNodeIndex(ALineIndex, FoldIndex: Integer;
|
||||
UseCloseNodes: boolean): integer;
|
||||
var
|
||||
@ -2686,6 +2698,14 @@ begin
|
||||
Node.FoldLvlStart := CurrentCodeFoldBlockLevel;
|
||||
Node.FoldLvlEnd := CurrentCodeFoldBlockLevel + EndOffs;
|
||||
Node.FoldType := Pointer(PtrInt(ABlockType));
|
||||
case ABlockType of
|
||||
cfbtRegion:
|
||||
node.FoldGroup := 2;
|
||||
cfbtIfDef:
|
||||
node.FoldGroup := 3;
|
||||
else
|
||||
node.FoldGroup := 1;
|
||||
end;
|
||||
if ABlockType in PascalWordTrippletRanges then
|
||||
Node.FoldAction := [sfaMarkup]
|
||||
else
|
||||
@ -2825,6 +2845,7 @@ begin
|
||||
then begin
|
||||
PasCodeFoldRange.DecLastLineCodeFoldLevelFix;
|
||||
dec(FStartCodeFoldBlockLevel);
|
||||
if FCatchNodeInfo then dec(FNodeInfoCount);
|
||||
end;
|
||||
if (PasCodeFoldRange.PasFoldEndLevel < FPasStartLevel) and
|
||||
(FPasStartLevel > 0)
|
||||
@ -3059,12 +3080,12 @@ begin
|
||||
FNodeInfoCount := 0;
|
||||
StartAtLineIndex(Line);
|
||||
fStringLen := 0;
|
||||
i := LastLineFoldLevelFix(Line);
|
||||
NextToEol;
|
||||
i := LastLineFoldLevelFix(Line+1);
|
||||
while i < 0 do begin
|
||||
EndCodeFoldBlock;
|
||||
inc(i);
|
||||
end;
|
||||
NextToEol;
|
||||
FCatchNodeInfo := False;
|
||||
FNodeInfoLine := Line;
|
||||
end;
|
||||
|
Loading…
Reference in New Issue
Block a user