mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-11-02 06:39:36 +01:00
SynEdit: Codefolding for user-selected blocks (Not saved to session)
git-svn-id: trunk@30151 -
This commit is contained in:
parent
64c43534c9
commit
2c0ed6c9f9
@ -1650,6 +1650,8 @@ begin
|
||||
FInternalBlockSelection.InvalidateLinesMethod := {$IFDEF FPC}@{$ENDIF}InvalidateLines;
|
||||
// No need for caret, on interanl block
|
||||
|
||||
FFoldedLinesView.BlockSelection := FBlockSelection;
|
||||
|
||||
FWordBreaker := TSynWordBreaker.Create;
|
||||
|
||||
RecreateMarkList;
|
||||
@ -1945,6 +1947,7 @@ begin
|
||||
SurrenderPrimarySelection;
|
||||
Highlighter := nil;
|
||||
Beautifier:=nil;
|
||||
FFoldedLinesView.BlockSelection := nil;
|
||||
// free listeners while other fields are still valid
|
||||
if Assigned(fHookedCommandHandlers) then begin
|
||||
for i := 0 to fHookedCommandHandlers.Count - 1 do
|
||||
|
||||
@ -281,6 +281,7 @@ type
|
||||
private
|
||||
FHighlighter: TSynCustomFoldHighlighter;
|
||||
FLines : TSynEditStrings;
|
||||
FSelection: TSynEditSelection;
|
||||
function GetLineCapabilities(ALineIdx: Integer): TSynEditFoldLineCapabilities;
|
||||
procedure SetHighLighter(const AValue: TSynCustomFoldHighlighter);
|
||||
public
|
||||
@ -313,6 +314,7 @@ type
|
||||
TSynEditFoldedView = class // TODO: class(TSynEditStringsLinked)
|
||||
private
|
||||
fCaret: TSynEditCaret;
|
||||
FBlockSelection: TSynEditSelection;
|
||||
FFoldProvider: TSynEditFoldProvider;
|
||||
fLines : TSynEditStrings;
|
||||
fFoldTree : TSynTextFoldAVLTree; // Folds are stored 1-based (the 1st line is 1)
|
||||
@ -334,12 +336,14 @@ type
|
||||
function GetTextIndex(index : Integer) : Integer;
|
||||
function GetFoldType(index : Integer) : TSynEditFoldLineCapabilities;
|
||||
function IsFolded(index : integer) : Boolean; // TextIndex
|
||||
procedure SetBlockSelection(const AValue: TSynEditSelection);
|
||||
procedure SetHighLighter(AValue: TSynCustomHighlighter);
|
||||
procedure SetTopLine(const ALine : integer);
|
||||
function GetTopTextIndex : integer;
|
||||
procedure SetTopTextIndex(const AIndex : integer);
|
||||
procedure SetLinesInWindow(const AValue : integer);
|
||||
protected
|
||||
procedure DoBlockSelChanged(Sender: TObject);
|
||||
Procedure CalculateMaps;
|
||||
function FoldNodeAtTextIndex(AStartIndex, ColIndex: Integer): TSynTextFoldAVLNode; (* Returns xth Fold at nth TextIndex (all lines in buffer) / 1-based *)
|
||||
function FixFolding(AStart : Integer; AMinEnd : Integer; aFoldTree : TSynTextFoldAVLTree) : Boolean;
|
||||
@ -371,6 +375,7 @@ type
|
||||
function TextIndexAddLines(aTextIndex, LineOffset : Integer) : Integer; (* Add/Sub to/from TextIndex (0-based) skipping folded *)
|
||||
function TextPosAddLines(aTextpos, LineOffset : Integer) : Integer; (* Add/Sub to/from TextPos (1-based) skipping folded *)
|
||||
|
||||
property BlockSelection: TSynEditSelection write SetBlockSelection;
|
||||
// Attributes for Visible-Lines-On-screen
|
||||
property Lines[index : Integer] : String (* Lines on screen / 0 = TopLine *)
|
||||
read GetLines; default;
|
||||
@ -2593,7 +2598,17 @@ var
|
||||
c: Integer;
|
||||
begin
|
||||
Result := [];
|
||||
if (FHighlighter = nil) or (ALineIdx < 0) then exit;
|
||||
if FSelection.SelAvail then begin
|
||||
if (FSelection.FirstLineBytePos.Y = ALineIdx+1) then Result := [cfHideStart];
|
||||
if (FSelection.LastLineBytePos.Y = ALineIdx+1) then Result := [cfFoldEnd];
|
||||
if (FSelection.FirstLineBytePos.Y = ALineIdx+1) and
|
||||
(FSelection.LastLineBytePos.Y = ALineIdx+1) then Result := [cfSingleLineHide];
|
||||
if (FSelection.FirstLineBytePos.Y < ALineIdx+1) and
|
||||
(FSelection.LastLineBytePos.Y > ALineIdx+1)
|
||||
then Result := [cfFoldBody];
|
||||
end;
|
||||
if (FHighlighter = nil) or (ALineIdx < 0) then
|
||||
exit;
|
||||
|
||||
FHighlighter.CurrentLines := FLines;
|
||||
if FHighlighter.FoldNestCount(ALineIdx - 1) > 0 then Result := Result + [cfFoldBody];
|
||||
@ -2631,7 +2646,10 @@ function TSynEditFoldProvider.FoldOpenCount(ALineIdx: Integer; AType: Integer =
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
if (FHighlighter = nil) or (ALineIdx < 0) then exit(0);
|
||||
if (FHighlighter = nil) or (ALineIdx < 0) then begin
|
||||
if (AType=0) and FSelection.SelAvail and (FSelection.FirstLineBytePos.Y=ALineIdx+1) then exit(1);
|
||||
exit(0);
|
||||
end;
|
||||
|
||||
FHighlighter.CurrentLines := FLines;
|
||||
Result := FHighlighter.FoldNodeInfoCount[ALineIdx, [sfaOpen, sfaFold]];
|
||||
@ -2649,19 +2667,47 @@ begin
|
||||
else
|
||||
if Result < 0 then
|
||||
Result := FHighlighter.FoldOpenCount(ALineIdx, AType);
|
||||
if (AType=0) and FSelection.SelAvail and (FSelection.FirstLineBytePos.Y=ALineIdx+1) then
|
||||
inc(Result);
|
||||
end;
|
||||
|
||||
function TSynEditFoldProvider.FoldOpenInfo(ALineIdx, AFoldIdx: Integer;
|
||||
AType: Integer = 0): TSynFoldNodeInfo;
|
||||
|
||||
function BlockSelInfo(NIdx: Integer): TSynFoldNodeInfo;
|
||||
begin
|
||||
Result.LineIndex := ALineIdx;
|
||||
Result.NodeIndex := NIdx;
|
||||
Result.LogXStart := FSelection.FirstLineBytePos.x;
|
||||
Result.LogXEnd := FSelection.FirstLineBytePos.x;
|
||||
Result.FoldLvlStart := 0;
|
||||
Result.NestLvlStart := 0;
|
||||
Result.NestLvlEnd := 1;
|
||||
Result.FoldLvlEnd := 1;
|
||||
Result.FoldAction := [sfaOpen, sfaFold, sfaFoldHide];
|
||||
Result.FoldType := nil;
|
||||
Result.FoldTypeCompatible := nil;
|
||||
Result.FoldGroup := -1;
|
||||
end;
|
||||
|
||||
var
|
||||
i, x: Integer;
|
||||
begin
|
||||
Result.FoldAction := [sfaInvalid];
|
||||
if (FHighlighter = nil) or (ALineIdx < 0) then exit;
|
||||
if (FHighlighter = nil) or (ALineIdx < 0) then begin
|
||||
if (AType=0) and FSelection.SelAvail and (FSelection.FirstLineBytePos.Y=ALineIdx+1) then
|
||||
exit(BlockSelInfo(0));
|
||||
exit;
|
||||
end;
|
||||
|
||||
FHighlighter.CurrentLines := FLines;
|
||||
if AType = 0 then
|
||||
Result := FHighlighter.FoldNodeInfo[ALineIdx, AFoldIdx, [sfaOpen, sfaFold]]
|
||||
if FSelection.SelAvail and (FSelection.FirstLineBytePos.Y=ALineIdx+1) and
|
||||
(AFoldIdx = FoldOpenCount(ALineIdx, 0)-1)
|
||||
then
|
||||
Result := BlockSelInfo(AFoldIdx-1)
|
||||
else
|
||||
Result := FHighlighter.FoldNodeInfo[ALineIdx, AFoldIdx, [sfaOpen, sfaFold]]
|
||||
else begin
|
||||
x := FHighlighter.FoldNodeInfoCount[ALineIdx, [sfaOpen, sfaFold]];
|
||||
i := 0;
|
||||
@ -2680,6 +2726,11 @@ end;
|
||||
|
||||
function TSynEditFoldProvider.FoldLineLength(ALine, AFoldIndex: Integer): integer;
|
||||
begin
|
||||
if FSelection.SelAvail and (FSelection.FirstLineBytePos.Y=ALine+1) and
|
||||
(AFoldIndex = FoldOpenCount(ALine, 0)-1)
|
||||
then
|
||||
exit(FSelection.LastLineBytePos.y - FSelection.FirstLineBytePos.y);
|
||||
|
||||
FHighlighter.CurrentLines := FLines;
|
||||
Result := FHighlighter.FoldLineLength(ALine, AFoldIndex);
|
||||
end;
|
||||
@ -2694,17 +2745,23 @@ begin
|
||||
Result.Column := 0;
|
||||
Result.ColumnLen := 0;
|
||||
Result.DefaultCollapsed := False;
|
||||
//if FSelection.SelAvail and (FSelection.FirstLineBytePos.Y=ALine) and
|
||||
// AFoldIndex = FoldOpenCount(ALineIdx, 0)-1
|
||||
//then begin
|
||||
//end;
|
||||
|
||||
if not assigned(FHighlighter) then
|
||||
exit;
|
||||
FHighlighter.CurrentLines := FLines;
|
||||
if NeedLen then begin
|
||||
Result.LineCount := FHighlighter.FoldLineLength(ALine, AFoldIndex);
|
||||
Result.LineCount := FoldLineLength(ALine, AFoldIndex);
|
||||
if HideLen then
|
||||
inc(Result.LineCount);
|
||||
end
|
||||
else
|
||||
Result.LineCount := -1;
|
||||
nd := FHighlighter.FoldNodeInfo[ALine, AFoldIndex, [sfaOpen, sfaFold]];
|
||||
nd := FoldOpenInfo(ALine, AFoldIndex, 0);
|
||||
// FHighlighter.FoldNodeInfo[ALine, AFoldIndex, [sfaOpen, sfaFold]];
|
||||
Result.Column := nd.LogXStart+1;
|
||||
Result.ColumnLen := nd.LogXEnd - nd.LogXStart;
|
||||
Result.DefaultCollapsed := (sfaDefaultCollapsed in nd.FoldAction);
|
||||
@ -2934,6 +2991,11 @@ begin
|
||||
CalculateMaps;
|
||||
end;
|
||||
|
||||
procedure TSynEditFoldedView.DoBlockSelChanged(Sender: TObject);
|
||||
begin
|
||||
CalculateMaps;
|
||||
end;
|
||||
|
||||
procedure TSynEditFoldedView.CalculateMaps;
|
||||
var
|
||||
i, tpos, cnt : Integer;
|
||||
@ -3027,6 +3089,16 @@ begin
|
||||
Result := fFoldTree.FindFoldForLine(index+1).IsInFold;
|
||||
end;
|
||||
|
||||
procedure TSynEditFoldedView.SetBlockSelection(const AValue: TSynEditSelection);
|
||||
begin
|
||||
if FBlockSelection <> nil then
|
||||
FBlockSelection.RemoveChangeHandler(@DoBlockSelChanged);
|
||||
FBlockSelection := AValue;
|
||||
if FBlockSelection <> nil then
|
||||
FBlockSelection.AddChangeHandler(@DoBlockSelChanged);
|
||||
FoldProvider.FSelection := AValue;
|
||||
end;
|
||||
|
||||
procedure TSynEditFoldedView.SetHighLighter(AValue: TSynCustomHighlighter);
|
||||
begin
|
||||
if not(AValue is TSynCustomFoldHighlighter) then
|
||||
|
||||
@ -2320,12 +2320,16 @@ begin
|
||||
AddCommand(emcCodeFoldExpand, False, mbLeft, ccAny, CDir, [], [], emcoCodeFoldExpandOne);
|
||||
if FTextMiddleClick <> moTMIgnore then
|
||||
AddCommand(emcCodeFoldCollaps, False, mbMiddle, ccAny, CDir, [], [], emcoCodeFoldCollapsOne);
|
||||
if CDir = cdUp then
|
||||
AddCommand(emcNone, False, mbLeft, ccAny, cdDown, [], []);
|
||||
end;
|
||||
with FGutterActionsFoldExp do begin
|
||||
AddCommand(emcCodeFoldCollaps, False, mbLeft, ccAny, CDir, [], [ssCtrl], emcoCodeFoldCollapsOne);
|
||||
AddCommand(emcCodeFoldCollaps, False, mbLeft, ccAny, CDir, [ssCtrl], [ssCtrl], emcoCodeFoldCollapsAll);
|
||||
if FTextMiddleClick <> moTMIgnore then
|
||||
AddCommand(emcCodeFoldCollaps, False, mbMiddle, ccAny, CDir, [], [], emcoCodeFoldCollapsOne);
|
||||
if CDir = cdUp then
|
||||
AddCommand(emcNone, False, mbLeft, ccAny, cdDown, [], []);
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user