mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-06-03 09:38:13 +02:00
SynEdit: Added markup module for source highlight from gutter-marks
git-svn-id: trunk@27893 -
This commit is contained in:
parent
bbebbdd3cd
commit
05da6877b9
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -2121,6 +2121,7 @@ components/synedit/syneditmarks.pp svneol=native#text/plain
|
||||
components/synedit/syneditmarkup.pp svneol=native#text/plain
|
||||
components/synedit/syneditmarkupbracket.pp svneol=native#text/plain
|
||||
components/synedit/syneditmarkupctrlmouselink.pp svneol=native#text/plain
|
||||
components/synedit/syneditmarkupguttermark.pp svneol=native#text/pascal
|
||||
components/synedit/syneditmarkuphighall.pp svneol=native#text/plain
|
||||
components/synedit/syneditmarkupselection.pp svneol=native#text/plain
|
||||
components/synedit/syneditmarkupspecialline.pp svneol=native#text/plain
|
||||
|
@ -39,7 +39,8 @@ implicitunits=synbeautifier syncompletion syndesignstringconstants \
|
||||
synedit syneditautocomplete syneditexport syneditfoldedview synedithighlighter \
|
||||
synedithighlighterfoldbase synedithighlighterxmlbase syneditkeycmds \
|
||||
syneditlazdsgn syneditlines syneditmarks \
|
||||
syneditmarkup syneditmarkupbracket syneditmarkupctrlmouselink syneditmarkuphighall \
|
||||
syneditmarkup syneditmarkupbracket syneditmarkupctrlmouselink \
|
||||
syneditmarkuphighall syneditmarkupguttermark\
|
||||
syneditmarkupselection syneditmarkupspecialline syneditmarkupwordgroup \
|
||||
syneditmiscclasses syneditmiscprocs syneditmousecmds syneditplugins \
|
||||
syneditpointclasses syneditregexsearch syneditsearch syneditstrconst synedittextbase \
|
||||
|
@ -43,6 +43,9 @@ uses
|
||||
SynHighlighterDiff,
|
||||
SynGutter, SynGutterChanges, SynGutterCodeFolding, SynGutterLineNumber,
|
||||
SynGutterMarks, SynGutterLineOverview,
|
||||
SynEditMarkup, SynEditMarkupBracket, SynEditMarkupCtrlMouseLink,
|
||||
SynEditMarkupHighAll, SynEditMarkupSelection, SynEditMarkupSpecialLine,
|
||||
SynEditMarkupWordGroup, SynEditMarkupGutterMark,
|
||||
SynPropertyEditObjectList, SynDesignStringConstants;
|
||||
|
||||
implementation
|
||||
|
@ -95,6 +95,7 @@ type
|
||||
Procedure EndMarkup; virtual;
|
||||
Function GetMarkupAttributeAtRowCol(const aRow, aCol : Integer) : TSynSelectedColor; virtual; abstract;
|
||||
Function GetNextMarkupColAfterRowCol(const aRow, aCol : Integer) : Integer; virtual; abstract;
|
||||
procedure MergeMarkupAttributeAtRowCol(const aRow, aCol, AEndCol : Integer; AMarkup: TSynSelectedColor); virtual;
|
||||
|
||||
// Notifications about Changes to the text
|
||||
Procedure TextChanged(aFirstCodeLine, aLastCodeLine: Integer); virtual;
|
||||
@ -148,9 +149,9 @@ type
|
||||
Procedure PrepareMarkupForRow(aRow : Integer); override;
|
||||
Procedure FinishMarkupForRow(aRow : Integer); override;
|
||||
Procedure EndMarkup; override;
|
||||
Function GetMarkupAttributeAtRowCol(const aRow, aCol : Integer) : TSynSelectedColor; override;
|
||||
Function GetNextMarkupColAfterRowCol(const aRow, aCol : Integer) : Integer; override;
|
||||
Procedure MergeMarkupAttributeAtRowCol(const aRow, aCol, AEndCol : Integer; AMarkup: TSynSelectedColor);
|
||||
Function GetMarkupAttributeAtRowCol(const aRow, aCol : Integer) : TSynSelectedColor; override;
|
||||
Function GetNextMarkupColAfterRowCol(const aRow, aCol : Integer) : Integer; override;
|
||||
procedure MergeMarkupAttributeAtRowCol(const aRow, aCol, AEndCol : Integer; AMarkup: TSynSelectedColor); override;
|
||||
|
||||
// Notifications about Changes to the text
|
||||
Procedure TextChanged(aFirstCodeLine, aLastCodeLine: Integer); override;
|
||||
@ -358,6 +359,16 @@ procedure TSynEditMarkup.EndMarkup;
|
||||
begin
|
||||
end;
|
||||
|
||||
procedure TSynEditMarkup.MergeMarkupAttributeAtRowCol(const aRow, aCol, AEndCol: Integer;
|
||||
AMarkup: TSynSelectedColor);
|
||||
var
|
||||
c: TSynSelectedColor;
|
||||
begin
|
||||
c := GetMarkupAttributeAtRowCol(aRow, aCol);
|
||||
if assigned(c) then
|
||||
AMarkup.Merge(c, aCol, AEndCol);
|
||||
end;
|
||||
|
||||
procedure TSynEditMarkup.TextChanged(aFirstCodeLine, aLastCodeLine: Integer);
|
||||
begin
|
||||
DoTextChanged(aFirstCodeLine, aLastCodeLine);
|
||||
@ -483,14 +494,11 @@ procedure TSynEditMarkupManager.MergeMarkupAttributeAtRowCol
|
||||
(const aRow, aCol, AEndCol: Integer; AMarkup: TSynSelectedColor);
|
||||
var
|
||||
i : integer;
|
||||
c : TSynSelectedColor;
|
||||
begin
|
||||
for i := 0 to fMarkUpList.Count-1 do begin
|
||||
if not TSynEditMarkup(fMarkUpList[i]).Enabled then continue;
|
||||
c := TSynEditMarkup(fMarkUpList[i]).GetMarkupAttributeAtRowCol(aRow, aCol);
|
||||
if assigned(c) then begin
|
||||
AMarkup.Merge(c, aCol, AEndCol);
|
||||
end;
|
||||
if TSynEditMarkup(fMarkUpList[i]).Enabled then
|
||||
TSynEditMarkup(fMarkUpList[i]).MergeMarkupAttributeAtRowCol
|
||||
(aRow, aCol, AEndCol, AMarkup);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
160
components/synedit/syneditmarkupguttermark.pp
Normal file
160
components/synedit/syneditmarkupguttermark.pp
Normal file
@ -0,0 +1,160 @@
|
||||
{-------------------------------------------------------------------------------
|
||||
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 SynEditMarkupGutterMark;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, Graphics, Controls, LCLProc,
|
||||
SynEditMarkup, SynEditMiscClasses, SynEditMarks;
|
||||
|
||||
type
|
||||
|
||||
TMarkSection = record
|
||||
StartX, EndX: Integer; // Physical
|
||||
Priority: Integer;
|
||||
Markup: TSynSelectedColor;
|
||||
end;
|
||||
|
||||
{ TSynEditMarkupMark }
|
||||
|
||||
TSynEditMarkupMark = class(TSynEditMark)
|
||||
private
|
||||
FSourceMarkup: TSynSelectedColor;
|
||||
public
|
||||
property SourceMarkup: TSynSelectedColor read FSourceMarkup write FSourceMarkup;
|
||||
end;
|
||||
|
||||
|
||||
{ TSynEditMarkupGutterMark }
|
||||
|
||||
TSynEditMarkupGutterMark = class(TSynEditMarkup)
|
||||
// TODO: subscribe to mark changes for line invalidation => currently done by synedit itself
|
||||
private
|
||||
FRowData: Array of TMarkSection;
|
||||
FWordBreaker: TSynWordBreaker;
|
||||
protected
|
||||
procedure DoMarkupChanged(AMarkup: TSynSelectedColor); override;
|
||||
public
|
||||
constructor Create(ASynEdit: TSynEditBase; AWordBreaker: TSynWordBreaker);
|
||||
|
||||
procedure PrepareMarkupForRow(ARow: Integer); override;
|
||||
function GetMarkupAttributeAtRowCol(const ARow, ACol: Integer): TSynSelectedColor; override;
|
||||
function GetNextMarkupColAfterRowCol(const ARow, ACol: Integer): Integer; override;
|
||||
//procedure MergeMarkupAttributeAtRowCol(const aRow, aCol, AEndCol : Integer; AMarkup: TSynSelectedColor); override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
SynEdit;
|
||||
|
||||
|
||||
{ TSynEditMarkupGutterMark }
|
||||
|
||||
procedure TSynEditMarkupGutterMark.DoMarkupChanged(AMarkup: TSynSelectedColor);
|
||||
begin
|
||||
inherited DoMarkupChanged(AMarkup);
|
||||
SynEdit.Invalidate;
|
||||
end;
|
||||
|
||||
constructor TSynEditMarkupGutterMark.Create(ASynEdit: TSynEditBase;
|
||||
AWordBreaker: TSynWordBreaker);
|
||||
begin
|
||||
FWordBreaker := AWordBreaker;
|
||||
inherited Create(ASynEdit);
|
||||
end;
|
||||
|
||||
procedure TSynEditMarkupGutterMark.PrepareMarkupForRow(ARow: Integer);
|
||||
var
|
||||
MLine: TSynEditMarkLine;
|
||||
i, j: Integer;
|
||||
s: string;
|
||||
begin
|
||||
MLine := TSynEdit(SynEdit).Marks.Line[ARow];
|
||||
if MLine = nil then begin
|
||||
SetLength(FRowData, 0);
|
||||
exit;
|
||||
end;
|
||||
SetLength(FRowData, MLine.Count);
|
||||
|
||||
j := 0;
|
||||
for i := 0 to MLine.Count - 1 do begin
|
||||
if not ( (MLine[i] is TSynEditMarkupMark) and
|
||||
(TSynEditMarkupMark(MLine[i]).SourceMarkup <> nil) )
|
||||
then
|
||||
continue;
|
||||
|
||||
FRowData[i].Markup := TSynEditMarkupMark(MLine[i]).SourceMarkup;
|
||||
FRowData[i].Priority := MLine[i].Priority;
|
||||
|
||||
s := Lines[MLine[i].Line - 1];
|
||||
FRowData[i].StartX := LogicalToPhysicalPos
|
||||
(Point(FWordBreaker.PrevBoundary(s, MLine[i].Column, True), MLine[i].Line)).x;
|
||||
FRowData[i].EndX := LogicalToPhysicalPos
|
||||
(Point(FWordBreaker.NextBoundary(s, MLine[i].Column), MLine[i].Line)).x;
|
||||
|
||||
if (FRowData[i].StartX > 0) and (FRowData[i].EndX > 0) then
|
||||
inc(j);
|
||||
end;
|
||||
|
||||
SetLength(FRowData, j);
|
||||
end;
|
||||
|
||||
function TSynEditMarkupGutterMark.GetMarkupAttributeAtRowCol(const ARow,
|
||||
ACol: Integer): TSynSelectedColor;
|
||||
var
|
||||
i, FoundPri: Integer;
|
||||
begin
|
||||
FoundPri := 0;
|
||||
for i := 0 to length(FRowData) - 1 do begin
|
||||
if (FRowData[i].StartX <= ACol) and (FRowData[i].EndX > ACol) and
|
||||
( (FRowData[i].Priority < FoundPri) or (i = 0) )
|
||||
then begin
|
||||
Result := FRowData[i].Markup;
|
||||
Result.StartX := FRowData[i].StartX;
|
||||
Result.EndX := FRowData[i].EndX-1;
|
||||
FoundPri := FRowData[i].Priority;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TSynEditMarkupGutterMark.GetNextMarkupColAfterRowCol(const ARow,
|
||||
ACol: Integer): Integer;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
Result := -1;
|
||||
if length(FRowData) = 0 then
|
||||
exit;
|
||||
for i := 0 to length(FRowData) - 1 do begin
|
||||
if FRowData[i].StartX < Result then
|
||||
Result := FRowData[0].StartX;;
|
||||
if FRowData[i].EndX < Result then
|
||||
Result := FRowData[0].EndX;;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
@ -68,6 +68,7 @@ type
|
||||
procedure Reset;
|
||||
|
||||
// aX is the position between the chars (as in CaretX)
|
||||
// 1 is in front of the first char
|
||||
function IsInWord (aLine: String; aX: Integer
|
||||
): Boolean;
|
||||
function IsAtWordStart(aLine: String; aX: Integer): Boolean;
|
||||
@ -82,6 +83,8 @@ type
|
||||
aIncludeCurrent: Boolean = False): Integer;
|
||||
|
||||
function NextBoundary (aLine: String; aX: Integer): Integer;
|
||||
function PrevBoundary (aLine: String; aX: Integer;
|
||||
aIncludeCurrent: Boolean = False): Integer;
|
||||
|
||||
property IdentChars: TSynIdentChars read FIdentChars write SetIdentChars;
|
||||
property WordChars: TSynIdentChars read FWordChars;
|
||||
@ -1467,6 +1470,25 @@ begin
|
||||
Result := aX;
|
||||
end;
|
||||
|
||||
function TSynWordBreaker.PrevBoundary(aLine: String; aX: Integer;
|
||||
aIncludeCurrent: Boolean): Integer;
|
||||
var
|
||||
len: Integer;
|
||||
begin
|
||||
len := Length(aLine);
|
||||
if not aIncludeCurrent then dec(ax);
|
||||
if (aX < 1) or (aX > len) then exit(-1);
|
||||
|
||||
if (aLine[aX] in FWordChars) then
|
||||
while (aX > 1) and (aLine[aX] in FWordChars) do dec(ax)
|
||||
else
|
||||
if (aLine[aX] in FWordBreakChars) then
|
||||
while (aX > 1) and (aLine[aX] in FWordBreakChars) do dec(ax)
|
||||
else
|
||||
while (aX > 1) and (aLine[aX] in FWhiteChars) do dec(ax);
|
||||
Result := aX + 1;
|
||||
end;
|
||||
|
||||
{ TSynMethodList }
|
||||
|
||||
function TSynMethodList.IndexToObjectIndex(const AnObject: TObject; AnIndex: Integer): integer;
|
||||
|
Loading…
Reference in New Issue
Block a user