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