mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-06-11 05:38:27 +02:00
SynEdit: Highlight Begin/End pairs
git-svn-id: trunk@18436 -
This commit is contained in:
parent
ebb9b257f7
commit
42a27dba3d
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -1430,6 +1430,7 @@ components/synedit/syneditmarkupctrlmouselink.pp svneol=native#text/plain
|
||||
components/synedit/syneditmarkuphighall.pp svneol=native#text/plain
|
||||
components/synedit/syneditmarkupselection.pp svneol=native#text/plain
|
||||
components/synedit/syneditmarkupspecialline.pp svneol=native#text/plain
|
||||
components/synedit/syneditmarkupwordgroup.pp svneol=native#text/plain
|
||||
components/synedit/syneditmiscclasses.pp svneol=native#text/pascal
|
||||
components/synedit/syneditmiscprocs.pp svneol=native#text/pascal
|
||||
components/synedit/syneditplugins.pas svneol=native#text/pascal
|
||||
|
@ -76,7 +76,7 @@ uses
|
||||
SynEditTypes, SynEditSearch, SynEditKeyCmds, SynEditMiscProcs,
|
||||
SynEditPointClasses, SynBeautifier, SynEditMarks,
|
||||
{$ifdef SYN_LAZARUS}
|
||||
SynEditMarkup, SynEditMarkupHighAll, SynEditMarkupBracket,
|
||||
SynEditMarkup, SynEditMarkupHighAll, SynEditMarkupBracket, SynEditMarkupWordGroup,
|
||||
SynEditMarkupCtrlMouseLink, SynEditMarkupSpecialLine, SynEditMarkupSelection,
|
||||
SynEditTextBase, SynEditTextTrimmer, SynEditFoldedView, SynEditTextTabExpander,
|
||||
SynGutterBase, SynGutter, SynGutterCodeFolding, SynGutterChanges,
|
||||
@ -334,6 +334,7 @@ type
|
||||
fMarkupHighAll : TSynEditMarkupHighlightAll;
|
||||
fMarkupHighCaret : TSynEditMarkupHighlightAllCaret;
|
||||
fMarkupBracket : TSynEditMarkupBracket;
|
||||
fMarkupWordGroup : TSynEditMarkupWordGroup;
|
||||
fMarkupCtrlMouse : TSynEditMarkupCtrlMouseLink;
|
||||
fMarkupSpecialLine : TSynEditMarkupSpecialLine;
|
||||
fMarkupSelection : TSynEditMarkupSelection;
|
||||
@ -1465,6 +1466,7 @@ begin
|
||||
fMarkupHighCaret.Selection := FBlockSelection;
|
||||
fMarkupHighAll := TSynEditMarkupHighlightAll.Create(self);
|
||||
fMarkupBracket := TSynEditMarkupBracket.Create(self);
|
||||
fMarkupWordGroup := TSynEditMarkupWordGroup.Create(self);
|
||||
fMarkupCtrlMouse := TSynEditMarkupCtrlMouseLink.Create(self);
|
||||
fMarkupSpecialLine := TSynEditMarkupSpecialLine.Create(self);
|
||||
fMarkupSelection := TSynEditMarkupSelection.Create(self, FBlockSelection);
|
||||
@ -1475,6 +1477,7 @@ begin
|
||||
fMarkupManager.AddMarkUp(fMarkupHighAll);
|
||||
fMarkupManager.AddMarkUp(fMarkupCtrlMouse);
|
||||
fMarkupManager.AddMarkUp(fMarkupBracket);
|
||||
fMarkupManager.AddMarkUp(fMarkupWordGroup);
|
||||
fMarkupManager.AddMarkUp(fMarkupSelection);
|
||||
fMarkupManager.Lines := TSynEditStrings(FTheLinesView);
|
||||
fMarkupManager.InvalidateLinesMethod := @InvalidateLines;
|
||||
@ -6218,6 +6221,7 @@ begin
|
||||
end;
|
||||
fHighlighter := Value;
|
||||
fMarkupHighCaret.Highlighter := Value;
|
||||
fMarkupWordGroup.Highlighter := Value;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
if fHighlighter<>nil then begin
|
||||
fHighlighter.ResetRange;
|
||||
|
@ -49,7 +49,7 @@ uses
|
||||
{$ENDIF}
|
||||
SynEditTypes,
|
||||
SynEditMiscClasses,
|
||||
SynEditTextBuffer;
|
||||
SynEditTextBuffer, SynEditTextBase;
|
||||
|
||||
{$DEFINE _Gp_MustEnhanceRegistry}
|
||||
{$IFDEF SYN_COMPILER_4_UP}
|
||||
@ -288,6 +288,8 @@ type
|
||||
function SaveToFile(AFileName: String): boolean; //DDH 10/16/01
|
||||
procedure HookAttrChangeEvent(ANotifyEvent: TNotifyEvent);
|
||||
procedure UnhookAttrChangeEvent(ANotifyEvent: TNotifyEvent);
|
||||
Function GetWordTriplet(LogicalCaret: TPoint; Lines: TSynEditStrings;
|
||||
out Y1, XB1, XE1, Y2, XB2, XE2, Y3, XB3, XE3: Integer): Boolean; virtual;
|
||||
property IdentChars: TSynIdentChars read GetIdentChars;
|
||||
property WordBreakChars: TSynIdentChars read fWordBreakChars write SetWordBreakChars;
|
||||
property LanguageName: string read GetLanguageName;
|
||||
@ -1259,6 +1261,13 @@ begin
|
||||
fAttrChangeHooks.Remove(ANotifyEvent);
|
||||
end;
|
||||
|
||||
function TSynCustomHighlighter.GetWordTriplet(LogicalCaret: TPoint;
|
||||
Lines: TSynEditStrings; out Y1, XB1, XE1, Y2, XB2, XE2, Y3, XB3, XE3: Integer
|
||||
): Boolean;
|
||||
begin
|
||||
Result := False;
|
||||
end;
|
||||
|
||||
procedure TSynCustomHighlighter.SetEnabled(const Value: boolean);
|
||||
begin
|
||||
if fEnabled <> Value then
|
||||
@ -1525,6 +1534,7 @@ begin
|
||||
// add a copy
|
||||
Result:=TSynCustomHighlighterRangeClass(Range.ClassType).Create(Range);
|
||||
FItems.Add(Result);
|
||||
if (FItems.Count mod 16) = 0 then DebugLn(['---------- TSynCustomHighlighterRanges Nodes.Count = ', FItems.Count]);
|
||||
end;
|
||||
//debugln('TSynCustomHighlighterRanges.GetEqual A ',dbgs(Node),' ',dbgs(Result.Compare(Range)),' ',dbgs(Result.CodeFoldStackSize));
|
||||
end;
|
||||
|
255
components/synedit/syneditmarkupwordgroup.pp
Normal file
255
components/synedit/syneditmarkupwordgroup.pp
Normal file
@ -0,0 +1,255 @@
|
||||
{-------------------------------------------------------------------------------
|
||||
The contents of this file are subject to the Mozilla Public License
|
||||
Version 1.1 (the "License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
http://www.mozilla.org/MPL/
|
||||
|
||||
Software distributed under the License is distributed on an "AS IS" basis,
|
||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
||||
the specific language governing rights and limitations under the License.
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of the
|
||||
GNU General Public License Version 2 or later (the "GPL"), in which case
|
||||
the provisions of the GPL are applicable instead of those above.
|
||||
If you wish to allow use of your version of this file only under the terms
|
||||
of the GPL and not to allow others to use your version of this file
|
||||
under the MPL, indicate your decision by deleting the provisions above and
|
||||
replace them with the notice and other provisions required by the GPL.
|
||||
If you do not delete the provisions above, a recipient may use your version
|
||||
of this file under either the MPL or the GPL.
|
||||
|
||||
-------------------------------------------------------------------------------}
|
||||
unit SynEditMarkupWordGroup;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, Graphics, SynEditMarkup, SynEditMiscClasses, Controls,
|
||||
LCLProc, SynEditHighlighter;
|
||||
|
||||
type
|
||||
|
||||
TWordPoint = record
|
||||
Y, X, X2: Integer;
|
||||
end;
|
||||
|
||||
|
||||
{ TSynEditMarkupWordGroup }
|
||||
|
||||
TSynEditMarkupWordGroup = class(TSynEditMarkup)
|
||||
private
|
||||
// Physical Position
|
||||
FHighlightPos1: TWordPoint;
|
||||
FHighlightPos2: TWordPoint;
|
||||
FHighlightPos3: TWordPoint;
|
||||
FHighlighter: TSynCustomHighlighter;
|
||||
procedure SetHighlighter(const AValue: TSynCustomHighlighter);
|
||||
protected
|
||||
procedure FindMatchingWords(PhysCaret: TPoint;
|
||||
out Word1, Word2, Word3: TWordPoint);
|
||||
procedure DoCaretChanged(OldCaret : TPoint); override;
|
||||
procedure DoTopLineChanged(OldTopLine : Integer); override;
|
||||
procedure DoLinesInWindoChanged(OldLinesInWindow : Integer); override;
|
||||
procedure DoTextChanged(StartLine, EndLine : Integer); override;
|
||||
procedure DoMarkupChanged(AMarkup: TSynSelectedColor); override;
|
||||
procedure InvalidateCurrentHighlight;
|
||||
public
|
||||
constructor Create(ASynEdit: TCustomControl);
|
||||
|
||||
function GetMarkupAttributeAtRowCol(const aRow, aCol: Integer): TSynSelectedColor; override;
|
||||
function GetNextMarkupColAfterRowCol(const aRow, aCol: Integer): Integer; override;
|
||||
|
||||
property Highlighter: TSynCustomHighlighter
|
||||
read FHighlighter write SetHighlighter;
|
||||
end;
|
||||
|
||||
implementation
|
||||
uses
|
||||
SynEdit;
|
||||
|
||||
Function CompareWordPoints(P1, P2: TWordPoint): Integer;
|
||||
begin
|
||||
if P1.Y < P2.Y then Exit(-1);
|
||||
if P1.Y > P2.Y then Exit(+1);
|
||||
If P1.X < P2.X then Exit(-1);
|
||||
If P1.X > P2.X then Exit(+1);
|
||||
If P1.X2 < P2.X2 then Exit(-1);
|
||||
If P1.X2 > P2.X2 then Exit(+1);
|
||||
Result := 0;
|
||||
end;
|
||||
|
||||
Function PointToWordPoint(P1: TPoint): TWordPoint;
|
||||
begin
|
||||
Result.Y := P1.Y;
|
||||
Result.X := P1.X;
|
||||
Result.X2 := P1.X+1;
|
||||
end;
|
||||
|
||||
{ TSynEditMarkupWordGroup }
|
||||
|
||||
constructor TSynEditMarkupWordGroup.Create(ASynEdit : TCustomControl);
|
||||
begin
|
||||
inherited Create(ASynEdit);
|
||||
FHighlightPos1.Y := -1;
|
||||
FHighlightPos2.Y := -1;
|
||||
MarkupInfo.Foreground := clNone;// clNone;
|
||||
MarkupInfo.FrameColor := clred;// clNone;
|
||||
MarkupInfo.Background := clNone;
|
||||
MarkupInfo.Style := [];
|
||||
MarkupInfo.StyleMask := [];
|
||||
end;
|
||||
|
||||
procedure TSynEditMarkupWordGroup.SetHighlighter(const AValue: TSynCustomHighlighter);
|
||||
begin
|
||||
FHighlighter := AValue;
|
||||
end;
|
||||
|
||||
procedure TSynEditMarkupWordGroup.FindMatchingWords(PhysCaret: TPoint;
|
||||
out Word1, Word2, Word3: TWordPoint);
|
||||
var
|
||||
LogCaretXY: TPoint;
|
||||
begin
|
||||
Word1.Y := -1;
|
||||
Word2.Y := -1;
|
||||
Word3.Y := -1;
|
||||
if (not assigned(Lines)) or (not MarkupInfo.IsEnabled) or
|
||||
(PhysCaret.Y < 1) or (PhysCaret.Y > Lines.Count) or (PhysCaret.X < 1)
|
||||
then
|
||||
Exit;
|
||||
|
||||
// Check for Begin-End like pairs
|
||||
if not assigned(FHighlighter) then Exit;
|
||||
LogCaretXY := TSynEdit(SynEdit).PhysicalToLogicalPos(PhysCaret);
|
||||
if FHighlighter.GetWordTriplet(LogCaretXY, Lines,
|
||||
Word1.Y, Word1.X, Word1.X2,
|
||||
Word3.Y, Word3.X, Word3. X2,
|
||||
Word2.Y, Word2.X, Word2. X2
|
||||
) then
|
||||
exit;
|
||||
|
||||
// In Case GetWordTriplet did set them
|
||||
Word1.Y := -1;
|
||||
Word2.Y := -1;
|
||||
Word3.Y := -1;
|
||||
end;
|
||||
|
||||
procedure TSynEditMarkupWordGroup.DoCaretChanged(OldCaret: TPoint);
|
||||
begin
|
||||
InvalidateCurrentHighlight;
|
||||
end;
|
||||
|
||||
procedure TSynEditMarkupWordGroup.DoTopLineChanged(OldTopLine: Integer);
|
||||
begin
|
||||
InvalidateCurrentHighlight;
|
||||
end;
|
||||
|
||||
procedure TSynEditMarkupWordGroup.DoLinesInWindoChanged(OldLinesInWindow: Integer);
|
||||
begin
|
||||
InvalidateCurrentHighlight;
|
||||
end;
|
||||
|
||||
procedure TSynEditMarkupWordGroup.DoTextChanged(StartLine, EndLine: Integer);
|
||||
begin
|
||||
InvalidateCurrentHighlight;
|
||||
end;
|
||||
|
||||
procedure TSynEditMarkupWordGroup.DoMarkupChanged(AMarkup: TSynSelectedColor);
|
||||
begin
|
||||
InvalidateCurrentHighlight;
|
||||
end;
|
||||
|
||||
procedure TSynEditMarkupWordGroup.InvalidateCurrentHighlight;
|
||||
var
|
||||
NewPos, NewAntiPos, NewMiddlePos : TWordPoint;
|
||||
begin
|
||||
FindMatchingWords(TSynEdit(SynEdit).CaretXY, NewPos, NewAntiPos, NewMiddlePos);
|
||||
|
||||
// invalidate old highlighting, if changed
|
||||
if (FHighlightPos1.Y > 0)
|
||||
and (CompareWordPoints(FHighlightPos1, NewPos) <> 0)
|
||||
then
|
||||
InvalidateSynLines(FHighlightPos1.Y,FHighlightPos1.Y);
|
||||
|
||||
if (FHighlightPos2.Y > 0)
|
||||
and (CompareWordPoints(FHighlightPos2, NewAntiPos) <> 0)
|
||||
then
|
||||
InvalidateSynLines(FHighlightPos2.Y,FHighlightPos2.Y);
|
||||
|
||||
if (FHighlightPos3.Y > 0)
|
||||
and (CompareWordPoints(FHighlightPos3, NewMiddlePos) <> 0)
|
||||
then
|
||||
InvalidateSynLines(FHighlightPos3.Y,FHighlightPos3.Y);
|
||||
|
||||
// invalidate new highlighting, if changed
|
||||
if (NewPos.Y>0)
|
||||
and (CompareWordPoints(FHighlightPos1, NewPos) <> 0) then
|
||||
InvalidateSynLines(NewPos.Y, NewPos.Y);
|
||||
|
||||
if (NewAntiPos.Y>0)
|
||||
and (CompareWordPoints(FHighlightPos2, NewAntiPos) <> 0) then
|
||||
InvalidateSynLines(NewAntiPos.Y, NewAntiPos.Y);
|
||||
|
||||
if (NewMiddlePos.Y>0)
|
||||
and (CompareWordPoints(FHighlightPos3, NewMiddlePos) <> 0) then
|
||||
InvalidateSynLines(NewMiddlePos.Y, NewMiddlePos.Y);
|
||||
|
||||
FHighlightPos1 := NewPos;
|
||||
FHighlightPos2 := NewAntiPos;
|
||||
FHighlightPos3 := NewMiddlePos;
|
||||
// DebugLn('TCustomSynEdit.InvalidateCurrentHighlight C P=',dbgs(NewPos),' A=',dbgs(NewAntiPos), ' LP=',dbgs(fLogicalPos),' LA',dbgs(fLogicalAntiPos));
|
||||
end;
|
||||
|
||||
function TSynEditMarkupWordGroup.GetMarkupAttributeAtRowCol(const aRow, aCol: Integer) : TSynSelectedColor;
|
||||
begin
|
||||
Result := nil;
|
||||
if (FHighlightPos1.y = aRow) and
|
||||
(aCol >= FHighlightPos1.x) and (aCol < FHighlightPos1.X2) then
|
||||
begin
|
||||
Result := MarkupInfo;
|
||||
MarkupInfo.StartX := aCol;
|
||||
MarkupInfo.EndX := FHighlightPos1.X2 - 1;
|
||||
end
|
||||
else
|
||||
if (FHighlightPos3.y = aRow) and
|
||||
(aCol >= FHighlightPos3.x) and (aCol < FHighlightPos3.X2) then
|
||||
begin
|
||||
Result := MarkupInfo;
|
||||
MarkupInfo.StartX := aCol;
|
||||
MarkupInfo.EndX := FHighlightPos3.X2 - 1;
|
||||
end
|
||||
else
|
||||
if (FHighlightPos2.y = aRow) and
|
||||
(aCol >= FHighlightPos2.x) and (aCol < FHighlightPos2.X2) then
|
||||
begin
|
||||
Result := MarkupInfo;
|
||||
MarkupInfo.StartX := aCol;
|
||||
MarkupInfo.EndX := FHighlightPos2.X2 - 1;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TSynEditMarkupWordGroup.GetNextMarkupColAfterRowCol(const aRow, aCol: Integer) : Integer;
|
||||
Procedure CheckCol(Column: Integer; var Result: Integer);
|
||||
begin
|
||||
if (Column <= aCol) or ((Result >= 0) and (Result < Column)) then exit;
|
||||
Result := Column;
|
||||
end;
|
||||
begin
|
||||
Result := -1;
|
||||
if (FHighlightPos1.y = aRow) then begin
|
||||
CheckCol(FHighlightPos1.X, Result);
|
||||
CheckCol(FHighlightPos1.X2, Result);
|
||||
end;
|
||||
if (FHighlightPos3.y = aRow) then begin
|
||||
CheckCol(FHighlightPos3.X, Result);
|
||||
CheckCol(FHighlightPos3.X2, Result);
|
||||
end;
|
||||
if (FHighlightPos2.y = aRow) then begin
|
||||
CheckCol(FHighlightPos2.X, Result);
|
||||
CheckCol(FHighlightPos2.X2, Result);
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
@ -58,7 +58,7 @@ uses
|
||||
Windows, Messages,
|
||||
{$ENDIF}
|
||||
Classes, Registry, Controls,
|
||||
SynEditTypes, SynEditHighlighter, SynEditTextBuffer;
|
||||
SynEditTypes, SynEditHighlighter, SynEditTextBuffer, SynEditTextBase;
|
||||
|
||||
type
|
||||
TtkTokenKind = (tkAsm, tkComment, tkIdentifier, tkKey, tkNull, tkNumber,
|
||||
@ -103,6 +103,13 @@ type
|
||||
cfbtProgram,
|
||||
cfbtRecord
|
||||
);
|
||||
TPascalWordTrippletRanges = set of TPascalCodeFoldBlockType;
|
||||
|
||||
const
|
||||
PascalWordTrippletRanges: TPascalWordTrippletRanges =
|
||||
[cfbtBeginEnd, cfbtProcedure, cfbtClass, cfbtProgram, cfbtRecord];
|
||||
type
|
||||
|
||||
TPascalCompilerMode = (
|
||||
pcmObjFPC,
|
||||
pcmDelphi,
|
||||
@ -119,6 +126,7 @@ type
|
||||
FMode: TPascalCompilerMode;
|
||||
FBracketNestLevel : Integer;
|
||||
FLastLineCodeFoldLevelFix: integer;
|
||||
FMinimumCodeFoldBlockLevel: Integer;
|
||||
public
|
||||
procedure Clear; override;
|
||||
function Compare(Range: TSynCustomHighlighterRange): integer; override;
|
||||
@ -128,8 +136,14 @@ type
|
||||
procedure DecLastLineCodeFoldLevelFix;
|
||||
property Mode: TPascalCompilerMode read FMode write FMode;
|
||||
property BracketNestLevel: integer read FBracketNestLevel write FBracketNestLevel;
|
||||
property LastLineCodeFoldLevelFix: integer read FLastLineCodeFoldLevelFix
|
||||
write FLastLineCodeFoldLevelFix;
|
||||
// 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;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
@ -179,6 +193,7 @@ type
|
||||
{$ENDIF}
|
||||
fD4syntax: boolean;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
function GetPasCodeFoldRange: TSynPasSynRange;
|
||||
procedure SetCompilerMode(const AValue: TPascalCompilerMode);
|
||||
function TextComp(aText: PChar): Boolean;
|
||||
function KeyHash: Integer;
|
||||
@ -315,6 +330,7 @@ type
|
||||
{$ENDIF}
|
||||
procedure EndCodeFoldBlockLastLine;
|
||||
function GetLastLineCodeFoldLevelFix: integer; override;
|
||||
property PasCodeFoldRange: TSynPasSynRange read GetPasCodeFoldRange;
|
||||
public
|
||||
{$IFNDEF SYN_CPPB_1} class {$ENDIF}
|
||||
function GetCapabilities: TSynHighlighterCapabilities; override;
|
||||
@ -347,6 +363,8 @@ type
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
function TopPascalCodeFoldBlockType: TPascalCodeFoldBlockType;
|
||||
{$ENDIF}
|
||||
Function GetWordTriplet(LogicalCaret: TPoint; Lines: TSynEditStrings;
|
||||
out Y1, XB1, XE1, Y2, XB2, XE2, Y3, XB3, XE3: Integer): Boolean; override;
|
||||
published
|
||||
property AsmAttri: TSynHighlighterAttributes read fAsmAttri write fAsmAttri;
|
||||
property CommentAttri: TSynHighlighterAttributes read fCommentAttri
|
||||
@ -723,6 +741,11 @@ begin
|
||||
//DebugLn(['TSynPasSyn.SetCompilerMode FCompilerMode=',ord(FCompilerMode),' FNestedComments=',FNestedComments]);
|
||||
end;
|
||||
|
||||
function TSynPasSyn.GetPasCodeFoldRange: TSynPasSynRange;
|
||||
begin
|
||||
Result := TSynPasSynRange(CodeFoldRange);
|
||||
end;
|
||||
|
||||
{$ENDIF}
|
||||
|
||||
function TSynPasSyn.Func15: TtkTokenKind;
|
||||
@ -2149,6 +2172,7 @@ begin
|
||||
// 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}
|
||||
@ -2173,6 +2197,7 @@ procedure TSynPasSyn.ResetRange;
|
||||
begin
|
||||
fRange:= [rsAfterSemicolon]; // Begin of file = new Statement
|
||||
FStartCodeFoldBlockLevel:=0;
|
||||
FMinimumCodeFoldBlockLevel := 0;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
Inherited ResetRange;
|
||||
CompilerMode:=pcmDelphi;
|
||||
@ -2209,6 +2234,191 @@ begin
|
||||
Result:=TPascalCodeFoldBlockType(PtrUInt(inherited TopCodeFoldBlockType));
|
||||
end;
|
||||
|
||||
// ToDO: pass in Max for the search lines (Begin must be found always)
|
||||
function TSynPasSyn.GetWordTriplet(LogicalCaret: TPoint; Lines: TSynEditStrings;
|
||||
out Y1, XB1, XE1, Y2, XB2, XE2, Y3, XB3, XE3: Integer): Boolean;
|
||||
|
||||
function GetLevelBeforeCaret: Integer;
|
||||
var
|
||||
l: Integer;
|
||||
begin
|
||||
SetRange(Lines.Ranges[LogicalCaret.Y - 1]);
|
||||
FMinimumCodeFoldBlockLevel := CurrentCodeFoldBlockLevel;
|
||||
l := CurrentCodeFoldBlockLevel;
|
||||
SetLine(Lines[LogicalCaret.Y - 1], LogicalCaret.Y - 1);
|
||||
if (MinimumCodeFoldBlockLevel < CurrentCodeFoldBlockLevel)
|
||||
then Result := MinimumCodeFoldBlockLevel
|
||||
else Result := l;
|
||||
while (Run <= LogicalCaret.x - 1) and not GetEol do begin
|
||||
if (Run = LogicalCaret.x-1) and (Result <> CurrentCodeFoldBlockLevel) then
|
||||
break;
|
||||
FMinimumCodeFoldBlockLevel := CurrentCodeFoldBlockLevel;
|
||||
l := CurrentCodeFoldBlockLevel;
|
||||
Next;
|
||||
if (MinimumCodeFoldBlockLevel < CurrentCodeFoldBlockLevel)
|
||||
then Result := MinimumCodeFoldBlockLevel
|
||||
else Result := l;
|
||||
end;
|
||||
end;
|
||||
|
||||
function FindBegin(EndY, EndX, SeekLevel: Integer; out X1, X2: Integer;
|
||||
out FoldType: TPascalCodeFoldBlockType): integer; // Returns Line
|
||||
var
|
||||
MinLvl: Integer;
|
||||
begin
|
||||
Result := EndY;
|
||||
MinLvl := 0; // Search the current line always
|
||||
repeat
|
||||
SetRange(Lines.Ranges[Result - 1]);
|
||||
//PasCodeFoldRange.MinimumCodeFoldBlockLevel;
|
||||
if (EndX > 0) and (MinLvl <= SeekLevel) then begin
|
||||
// Search in current Line
|
||||
X1 := -1;
|
||||
// Use MinimumCodefoldlevel to detect theimplicit end of "var"/"type" blocks at the next "begin"
|
||||
FMinimumCodeFoldBlockLevel := CurrentCodeFoldBlockLevel;
|
||||
MinLvl := PasCodeFoldRange.MinimumCodeFoldBlockLevel; // Before SetLine = LastLine's MinLvl
|
||||
SetLine(Lines[Result - 1], Result - 1);
|
||||
while (Run <= EndX) and not GetEol do begin
|
||||
if (MinimumCodeFoldBlockLevel <= SeekLevel) then begin
|
||||
X1 := fTokenPos;
|
||||
X2 := Run;
|
||||
FoldType := TopPascalCodeFoldBlockType;
|
||||
end;
|
||||
FMinimumCodeFoldBlockLevel := CurrentCodeFoldBlockLevel;
|
||||
Next;
|
||||
end;
|
||||
if X1 >= 0 then exit;
|
||||
end
|
||||
else
|
||||
MinLvl := PasCodeFoldRange.MinimumCodeFoldBlockLevel; // Before SetLine = LastLine's MinLvl
|
||||
// Search previous lines
|
||||
EndX := MaxInt;
|
||||
dec(Result);
|
||||
until Result = 0; // should always exit before
|
||||
end;
|
||||
|
||||
function FindEnd(BeginY, BeginX2, SeekLevel: Integer;
|
||||
out X1, X2, LvlBefore: Integer): integer; // Returns Line
|
||||
var
|
||||
c, MinLvl : Integer;
|
||||
begin
|
||||
Result := BeginY;
|
||||
c := Lines.Count;
|
||||
MinLvl := 0; // CurrentLine always has samller Minlevel
|
||||
repeat
|
||||
SetRange(Lines.Ranges[Result-1]);
|
||||
if (MinLvl < SeekLevel) then begin
|
||||
// Search in current Line
|
||||
LvlBefore := CurrentCodeFoldBlockLevel;
|
||||
SetLine(Lines[Result - 1], Result - 1);
|
||||
if (FTokenPos < BeginX2) then
|
||||
begin
|
||||
while (FTokenPos < BeginX2) and not GetEol do
|
||||
Next;
|
||||
FMinimumCodeFoldBlockLevel := CurrentCodeFoldBlockLevel;
|
||||
end;
|
||||
while not GetEol do
|
||||
begin
|
||||
if CurrentCodeFoldBlockLevel < SeekLevel then
|
||||
begin
|
||||
X1 := fTokenPos;
|
||||
X2 := Run;
|
||||
exit
|
||||
end
|
||||
else if (MinimumCodeFoldBlockLevel < SeekLevel) or
|
||||
(CurrentCodeFoldBlockLevel + LastLineCodeFoldLevelFix < SeekLevel)
|
||||
then
|
||||
exit(-1); // This block ended in the previous line (implicit end)
|
||||
LvlBefore := CurrentCodeFoldBlockLevel;
|
||||
Next;
|
||||
end;
|
||||
end;
|
||||
// Search previous lines
|
||||
BeginX2 := 0;
|
||||
inc(Result);
|
||||
if Result < c-1 then begin
|
||||
SetRange(Lines.Ranges[Result]);
|
||||
MinLvl := PasCodeFoldRange.MinimumCodeFoldBlockLevel;
|
||||
end else begin
|
||||
MinLvl := 0;
|
||||
end;
|
||||
until Result = c;
|
||||
Result := -1;
|
||||
end;
|
||||
|
||||
var
|
||||
CurStartLevel, CurEndLevel, CurStartPosX, CurEndPosX, CurPosY: Integer;
|
||||
EndStartLevel: Integer;
|
||||
ft, ft2: TPascalCodeFoldBlockType;
|
||||
begin
|
||||
Result := False;
|
||||
|
||||
CurPosY := LogicalCaret.Y;
|
||||
CurStartLevel := GetLevelBeforeCaret;
|
||||
CurEndLevel := CurrentCodeFoldBlockLevel;
|
||||
CurStartPosX := fTokenPos; // 0 based
|
||||
CurEndPosX := Run; // 0 based
|
||||
|
||||
IF CurEndLevel > CurStartLevel then begin
|
||||
// block open: begin or middle
|
||||
if not (TopPascalCodeFoldBlockType in PascalWordTrippletRanges) then
|
||||
exit;
|
||||
|
||||
Y1 := CurPosY;
|
||||
XB1 := CurStartPosX;
|
||||
XE1 := CurEndPosX;
|
||||
|
||||
Y3 := FindEnd(CurPosY, CurEndPosX, CurEndLevel, XB3, XE3, EndStartLevel);
|
||||
if Y3 < 0 then exit(false);
|
||||
|
||||
Result := true;
|
||||
if (EndStartLevel - CurrentCodeFoldBlockLevel = 1) then begin;
|
||||
Y2:=-2;
|
||||
end else begin
|
||||
if CurStartLevel = CurrentCodeFoldBlockLevel
|
||||
then Y2 := FindBegin(Y3, XB3, CurrentCodeFoldBlockLevel+1, XB2, XE2, ft)
|
||||
else Y2 := FindBegin(Y3, XB3, CurrentCodeFoldBlockLevel, XB2, XE2, ft);
|
||||
if not (ft in PascalWordTrippletRanges) then
|
||||
Y2 := -1;
|
||||
end;
|
||||
end
|
||||
else
|
||||
if CurStartLevel - CurEndLevel = 1 then begin
|
||||
// block end, 1 lvl
|
||||
Y1 := FindBegin(CurPosY, CurStartPosX, CurEndLevel, XB1, XE1, ft);
|
||||
if not (ft in PascalWordTrippletRanges) then
|
||||
exit;
|
||||
Y2 := CurPosY;
|
||||
XB2 := CurStartPosX;
|
||||
XE2 := CurEndPosX;
|
||||
Y3 := -2;
|
||||
Result := true;
|
||||
end
|
||||
else
|
||||
if CurEndLevel < CurStartLevel then begin
|
||||
// block end, 2 lvl
|
||||
Y2 := FindBegin(CurPosY, CurStartPosX, CurEndLevel+1, XB2, XE2, ft);
|
||||
Y1 := FindBegin(Y2, XB2, CurEndLevel, XB1, XE1, ft2);
|
||||
if not (ft in PascalWordTrippletRanges) then
|
||||
Y2 := -1;
|
||||
if not (ft2 in PascalWordTrippletRanges) then
|
||||
Y1 := -1;
|
||||
if (Y2 = -1) and (Y1 = -1) then
|
||||
exit;
|
||||
Y3 := CurPosY;
|
||||
XB3 := CurStartPosX;
|
||||
XE3 := CurEndPosX;
|
||||
Result := true;
|
||||
end;
|
||||
|
||||
inc(XB1);
|
||||
inc(XE1);
|
||||
inc(XB2);
|
||||
inc(XE2);
|
||||
inc(XB3);
|
||||
inc(XE3);
|
||||
end;
|
||||
|
||||
function TSynPasSyn.StartPascalCodeFoldBlock(
|
||||
ABlockType: TPascalCodeFoldBlockType;
|
||||
SubBlock: boolean): TSynCustomCodeFoldBlock;
|
||||
@ -2446,6 +2656,7 @@ begin
|
||||
inherited Clear;
|
||||
FBracketNestLevel := 0;
|
||||
FLastLineCodeFoldLevelFix := 0;
|
||||
FMinimumCodeFoldBlockLevel := 0;
|
||||
end;
|
||||
|
||||
function TSynPasSynRange.Compare(Range: TSynCustomHighlighterRange): integer;
|
||||
@ -2456,6 +2667,8 @@ begin
|
||||
if Result<>0 then exit;
|
||||
Result := BracketNestLevel - TSynPasSynRange(Range).BracketNestLevel;
|
||||
if Result<>0 then exit;
|
||||
Result := FMinimumCodeFoldBlockLevel - TSynPasSynRange(Range).FMinimumCodeFoldBlockLevel;
|
||||
if Result<>0 then exit;
|
||||
Result := FLastLineCodeFoldLevelFix - TSynPasSynRange(Range).FLastLineCodeFoldLevelFix;
|
||||
end;
|
||||
|
||||
@ -2464,6 +2677,7 @@ begin
|
||||
inherited Assign(Src);
|
||||
FMode:=TSynPasSynRange(Src).FMode;
|
||||
FBracketNestLevel:=TSynPasSynRange(Src).FBracketNestLevel;
|
||||
FMinimumCodeFoldBlockLevel := TSynPasSynRange(Src).FMinimumCodeFoldBlockLevel;
|
||||
FLastLineCodeFoldLevelFix := TSynPasSynRange(Src).FLastLineCodeFoldLevelFix;
|
||||
end;
|
||||
|
||||
|
@ -40,7 +40,7 @@ uses
|
||||
Controls, Graphics, LCLProc, FileUtil, LResources,
|
||||
// synedit
|
||||
SynEdit, SynEditAutoComplete, SynEditHighlighter, SynEditKeyCmds,
|
||||
SynEditStrConst, SynEditMarkupBracket, SynEditMarkupHighAll,
|
||||
SynEditStrConst, SynEditMarkupBracket, SynEditMarkupHighAll, SynEditMarkupWordGroup,
|
||||
SynGutter, SynGutterBase, SynGutterCodeFolding, SynGutterLineNumber, SynGutterChanges,
|
||||
SynHighlighterCPP, SynHighlighterHTML, SynHighlighterJava, SynHighlighterLFM,
|
||||
SynHighlighterPas, SynHighlighterPerl, SynHighlighterPHP, SynHighlighterSQL,
|
||||
@ -92,7 +92,7 @@ type
|
||||
ahaInvalidBreakpoint, ahaUnknownBreakpoint,
|
||||
ahaErrorLine, ahaIncrementalSearch, ahaHighlightAll, ahaBracketMatch,
|
||||
ahaMouseLink, ahaLineNumber, ahaLineHighlight, ahaModifiedLine,
|
||||
ahaCodeFoldingTree, ahaHighlightWord, ahaFoldedCode);
|
||||
ahaCodeFoldingTree, ahaHighlightWord, ahaFoldedCode, ahaWordGroup);
|
||||
|
||||
TSingleColorAttribute = (scaGutter, scaRightMargin);
|
||||
|
||||
@ -116,7 +116,8 @@ const
|
||||
'Modified line',
|
||||
'Code folding tree',
|
||||
'Highlight current word',
|
||||
'Folded code'
|
||||
'Folded code',
|
||||
'Word-Brackets'
|
||||
);
|
||||
|
||||
SingleColorAttributes: array[TSingleColorAttribute] of String =
|
||||
@ -171,7 +172,8 @@ const
|
||||
{ ahaModifiedLine } (BG: clNone; FG: clGreen; FC: $00E9FC; Styles: []; StylesMask: []),
|
||||
{ ahaCodeFoldingTree } (BG: clWhite; FG: clSilver; FC: clNone; Styles: []; StylesMask: []),
|
||||
{ ahaHighlightWord } (BG: $E6E6E6; FG: clDefault; FC: clSilver; Styles: []; StylesMask: []),
|
||||
{ ahaFoldedCode } (BG: clWhite; FG: clSilver; FC: clSilver; Styles: []; StylesMask: [])
|
||||
{ ahaFoldedCode } (BG: clWhite; FG: clSilver; FC: clSilver; Styles: []; StylesMask: []),
|
||||
{ ahaWordGroup } (BG: clNone; FG: clNone; FC: clRed; Styles: []; StylesMask: [])
|
||||
);
|
||||
Single: (
|
||||
{ shaGutter } clBtnFace,
|
||||
@ -209,7 +211,8 @@ const
|
||||
{ ahaModifiedLine } (BG: clNone; FG: clGreen; FC: $00E9FC; Styles: []; StylesMask: []),
|
||||
{ ahaCodeFoldingTree } (BG: clDefault; FG: clSilver; FC: clNone; Styles: []; StylesMask: []),
|
||||
{ ahaHighlightWord } (BG: $303030; FG: clDefault; FC: clSilver; Styles: []; StylesMask: []),
|
||||
{ ahaFoldedCode } (BG: clDefault; FG: clSilver; FC: clSilver; Styles: []; StylesMask: [])
|
||||
{ ahaFoldedCode } (BG: clDefault; FG: clSilver; FC: clSilver; Styles: []; StylesMask: []),
|
||||
{ ahaWordGroup } (BG: clNone; FG: clNone; FC: clRed; Styles: []; StylesMask: [])
|
||||
);
|
||||
Single: (
|
||||
{ shaGutter } clBtnFace,
|
||||
@ -247,7 +250,8 @@ const
|
||||
{ ahaModifiedLine } (BG: clNone; FG: clGreen; FC: $00E9FC; Styles: []; StylesMask: []),
|
||||
{ ahaCodeFoldingTree } (BG: clDefault; FG: clSilver; FC: clNone; Styles: []; StylesMask: []),
|
||||
{ ahaHighlightWord } (BG: clDefault; FG: clDefault; FC: clSilver; Styles: []; StylesMask: []),
|
||||
{ ahaFoldedCode } (BG: clDefault; FG: clSilver; FC: clSilver; Styles: []; StylesMask: [])
|
||||
{ ahaFoldedCode } (BG: clDefault; FG: clSilver; FC: clSilver; Styles: []; StylesMask: []),
|
||||
{ ahaWordGroup } (BG: clNone; FG: clNone; FC: clRed; Styles: []; StylesMask: [])
|
||||
);
|
||||
Single: (
|
||||
{ shaGutter } clBtnFace,
|
||||
@ -285,7 +289,8 @@ const
|
||||
{ ahaModifiedLine } (BG: clNone; FG: clGreen; FC: $00E9FC; Styles: []; StylesMask: []),
|
||||
{ ahaCodeFoldingTree } (BG: clDefault; FG: clSilver; FC: clNone; Styles: []; StylesMask: []),
|
||||
{ ahaHighlightWord } (BG: clDefault; FG: clDefault; FC: clSilver; Styles: []; StylesMask: []),
|
||||
{ ahaFoldedCode } (BG: clDefault; FG: clSilver; FC: clSilver; Styles: []; StylesMask: [])
|
||||
{ ahaFoldedCode } (BG: clDefault; FG: clSilver; FC: clSilver; Styles: []; StylesMask: []),
|
||||
{ ahaWordGroup } (BG: clNone; FG: clNone; FC: clRed; Styles: []; StylesMask: [])
|
||||
);
|
||||
Single: (
|
||||
{ shaGutter } clBtnFace,
|
||||
@ -323,7 +328,8 @@ const
|
||||
{ ahaModifiedLine } (BG: $F4F4F4; FG: clLime; FC: clYellow;Styles: []; StylesMask: []),
|
||||
{ ahaCodeFoldingTree } (BG: $F4F4F4; FG: $CC9999; FC: clNone; Styles: []; StylesMask: []),
|
||||
{ ahaHighlightWord } (BG: clDefault; FG: clDefault; FC: $CCCCD6; Styles: []; StylesMask: []),
|
||||
{ ahaFoldedCode } (BG: clDefault; FG: $CC9999; FC: $CC9999; Styles: []; StylesMask: [])
|
||||
{ ahaFoldedCode } (BG: clDefault; FG: $CC9999; FC: $CC9999; Styles: []; StylesMask: []),
|
||||
{ ahaWordGroup } (BG: clNone; FG: clNone; FC: clRed; Styles: []; StylesMask: [])
|
||||
);
|
||||
Single: (
|
||||
{ shaGutter } clBtnFace,
|
||||
@ -2323,6 +2329,7 @@ begin
|
||||
SetMarkupColor(aSynEd.Highlighter, ahaFoldedCode, aSynEd.FoldedCodeColor);
|
||||
SetMarkupColor(aSynEd.Highlighter, ahaLineHighlight, aSynEd.LineHighlightColor);
|
||||
SetMarkupColorByClass(ahaHighlightWord, TSynEditMarkupHighlightAllCaret);
|
||||
SetMarkupColorByClass(ahaWordGroup, TSynEditMarkupWordGroup);
|
||||
SetGutterColorByClass(ahaLineNumber, TSynGutterLineNumber);
|
||||
SetGutterColorByClass(ahaModifiedLine, TSynGutterChanges);
|
||||
SetGutterColorByClass(ahaCodeFoldingTree, TSynGutterCodeFolding);
|
||||
|
Loading…
Reference in New Issue
Block a user