686
821
AddToUndoList: Boolean = false);
687
822
procedure UndoItem(Item: TSynEditUndoItem);
688
823
procedure UpdateCursor;
689
property PaintLockOwner: TSynEditBase read GetPaintLockOwner write SetPaintLockOwner;
691
{$IFDEF EnableDoubleBuf}
692
BufferBitmap: TBitmap; // the double buffer
694
SavedCanvas: TCanvas; // the normal TCustomControl canvas during paint
695
function GetChildOwner: TComponent; override;
696
procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
697
824
procedure DoOnCommandProcessed(Command: TSynEditorCommand;
698
825
AChar: TUTF8Char;
699
826
Data: pointer); virtual;
700
827
// no method DoOnDropFiles, intercept the WM_DROPFILES instead
701
procedure DoOnPaint; virtual;
702
828
procedure DoOnProcessCommand(var Command: TSynEditorCommand;
703
829
var AChar: TUTF8Char;
704
830
Data: pointer); virtual;
705
831
function DoOnReplaceText(const ASearch, AReplace: string;
706
832
Line, Column: integer): TSynReplaceAction; virtual;
707
{$IFNDEF SYN_LAZARUS}
708
function DoOnSpecialLineColors(Line: integer;
709
var Foreground, Background: TColor): boolean; virtual;
711
833
procedure DoOnStatusChange(Changes: TSynStatusChanges); virtual;
712
834
property LastMouseCaret: TPoint read FLastMouseCaret write SetLastMouseCaret;
714
835
function GetSelEnd: integer; //L505
715
836
function GetSelStart: integer;
716
837
procedure SetSelEnd(const Value: integer);
717
838
procedure SetSelStart(const Value: integer);
718
839
property TextView : TSynEditFoldedView read FFoldedLinesView;
719
840
property TopView: Integer read GetTopView write SetTopView; // TopLine converted into Visible(View) lines
721
841
function PasteFromClipboardEx(ClipHelper: TSynClipboardStream): Boolean;
722
842
function FindNextUnfoldedLine(iLine: integer; Down: boolean): Integer;
723
843
// Todo: Reduce the argument list of Creategutter
724
844
function CreateGutter(AOwner : TSynEditBase; ASide: TSynGutterSide;
725
845
ATextDrawer: TheTextDrawer): TSynGutter; virtual;
727
procedure FindMatchingBracket; virtual;
728
function FindMatchingBracket(PhysStartBracket: TPoint;
729
StartIncludeNeighborChars, MoveCaret,
730
SelectBrackets, OnlyVisible: Boolean
733
procedure CodeFoldAction(iLine: integer); deprecated;
735
procedure FoldAll(StartLevel : Integer = 0; IgnoreNested : Boolean = False);
736
procedure EraseBackground(DC: HDC); override;
738
procedure AddKey(Command: TSynEditorCommand; Key1: word; SS1: TShiftState;
739
Key2: word; SS2: TShiftState);
847
constructor Create(AOwner: TComponent); override;
848
destructor Destroy; override;
740
849
procedure AfterLoadFromFile;
741
procedure BeginUndoBlock;
742
procedure BeginUpdate;
851
procedure BeginUndoBlock{$IFDEF SynUndoDebugBeginEnd}(ACaller: String = ''){$ENDIF};
852
procedure BeginUpdate(WithUndoBlock: Boolean = True);
853
procedure EndUndoBlock{$IFDEF SynUndoDebugBeginEnd}(ACaller: String = ''){$ENDIF};
743
858
function CaretXPix: Integer;
744
859
function CaretYPix: Integer;
860
procedure EnsureCursorPosVisible;
861
procedure MoveCaretToVisibleArea;
862
procedure MoveCaretIgnoreEOL(const NewCaret: TPoint);
863
procedure MoveLogicalCaretIgnoreEOL(const NewLogCaret: TPoint);
865
property CaretX: Integer read GetCaretX write SetCaretX;
866
property CaretY: Integer read GetCaretY write SetCaretY;
867
property CaretXY: TPoint read GetCaretXY write SetCaretXY;// screen position
868
property LogicalCaretXY: TPoint read GetLogicalCaretXY write SetLogicalCaretXY;
871
procedure ClearSelection;
873
procedure SelectToBrace;
874
procedure SelectWord;
875
procedure SelectLine(WithLeadSpaces: Boolean = True);
876
procedure SelectParagraph;
878
property BlockBegin: TPoint read GetBlockBegin write SetBlockBegin; // Set Blockbegin. For none persistent also sets Blockend. Setting Caret may undo this and should be done before setting block
879
property BlockEnd: TPoint read GetBlockEnd write SetBlockEnd;
880
property SelStart: Integer read GetSelStart write SetSelStart;
881
property SelEnd: Integer read GetSelEnd write SetSelEnd;
882
property SelAvail: Boolean read GetSelAvail;
883
property SelText: string read GetSelText write SetSelTextExternal;
745
886
procedure ClearAll;
887
procedure InsertTextAtCaret(aText: String; aCaretMode : TSynCaretAdjustMode = scamEnd);
889
property TextBetweenPoints[aStartPoint, aEndPoint: TPoint]: String // Logical Points
890
read GetTextBetweenPoints write SetTextBetweenPointsSimple;
891
property TextBetweenPointsEx[aStartPoint, aEndPoint: TPoint; CaretMode: TSynCaretAdjustMode]: String
892
write SetTextBetweenPointsEx;
893
procedure SetTextBetweenPoints(aStartPoint, aEndPoint: TPoint;
894
const AValue: String;
895
aFlags: TSynEditTextFlags = [];
896
aCaretMode: TSynCaretAdjustMode = scamIgnore;
897
aMarksMode: TSynMarksAdjustMode = smaMoveUp;
898
aSelectionMode: TSynSelectionMode = smNormal
901
property LineText: string read GetLineText write SetLineText;
902
property Text: string read SynGetText write SynSetText; // No uncommited (trailing/trimmable) spaces
904
function GetLineState(ALine: Integer): TSynLineState;
905
procedure MarkTextAsSaved;
746
908
procedure ClearBookMark(BookMark: Integer);
747
procedure ClearSelection;
748
procedure CommandProcessor(Command:TSynEditorCommand;
750
Data:pointer); virtual;
909
function GetBookMark(BookMark: integer; var X, Y: integer): boolean;
910
procedure GotoBookMark(BookMark: Integer);
911
function IsBookmark(BookMark: integer): boolean;
912
procedure SetBookMark(BookMark: Integer; X: Integer; Y: Integer);
913
property Marks: TSynEditMarkList read fMarkList;
751
916
procedure ClearUndo;
919
property CanRedo: boolean read GetCanRedo;
920
property CanUndo: boolean read GetCanUndo;
752
923
procedure CopyToClipboard;
753
constructor Create(AOwner: TComponent); override;
754
924
procedure CutToClipboard;
755
destructor Destroy; override;
925
procedure PasteFromClipboard;
756
926
procedure DoCopyToClipboard(SText: string; FoldInfo: String = '');
927
property CanPaste: Boolean read GetCanPaste;
757
929
procedure DragDrop(Source: TObject; X, Y: Integer); override;
758
procedure EndUndoBlock;
760
procedure EnsureCursorPosVisible;
761
930
{$IFDEF SYN_COMPILER_4_UP}
762
931
function ExecuteAction(ExeAction: TBasicAction): boolean; override;
933
procedure CommandProcessor(Command:TSynEditorCommand;
935
Data:pointer); virtual;
764
936
procedure ExecuteCommand(Command: TSynEditorCommand;
765
937
const AChar: TUTF8Char; Data: pointer); virtual;
766
function GetBookMark(BookMark: integer; var X, Y: integer): boolean;
767
function GetHighlighterAttriAtRowCol(XY: TPoint; var Token: string;
768
var Attri: TSynHighlighterAttributes): boolean;
769
function GetHighlighterAttriAtRowColEx(XY: TPoint; var Token: string;
770
var TokenType, Start: Integer;
771
var Attri: TSynHighlighterAttributes): boolean; //L505
773
procedure GetWordBoundsAtRowCol(const XY: TPoint; var StartX, EndX: integer);
939
function GetHighlighterAttriAtRowCol(XY: TPoint; out Token: string;
940
out Attri: TSynHighlighterAttributes): boolean;
941
function GetHighlighterAttriAtRowColEx(XY: TPoint; out Token: string;
942
out TokenType, Start: Integer;
943
out Attri: TSynHighlighterAttributes): boolean; //L505
944
procedure GetWordBoundsAtRowCol(const XY: TPoint; out StartX, EndX: integer);
774
945
function GetWordAtRowCol(XY: TPoint): string;
775
946
function NextTokenPos: TPoint; virtual; deprecated; // use next word pos instead
776
947
function NextWordPos: TPoint; virtual;
826
990
procedure RegisterStatusChangedHandler(AStatusChangeProc: TStatusChangeEvent; AChanges: TSynStatusChanges);
827
991
procedure UnRegisterStatusChangedHandler(AStatusChangeProc: TStatusChangeEvent);
829
// RowColumnToPixels: Physical coords
830
function RowColumnToPixels(
831
{$IFDEF SYN_LAZARUS}const {$ENDIF}RowCol: TPoint): TPoint;
993
procedure RegisterBeforeMouseDownHandler(AHandlerProc: TMouseEvent);
994
procedure UnregisterBeforeMouseDownHandler(AHandlerProc: TMouseEvent);
996
procedure RegisterBeforeKeyDownHandler(AHandlerProc: TKeyEvent);
997
procedure UnregisterBeforeKeyDownHandler(AHandlerProc: TKeyEvent);
998
procedure RegisterBeforeKeyPressHandler(AHandlerProc: TKeyPressEvent);
999
procedure UnregisterBeforeKeyPressHandler(AHandlerProc: TKeyPressEvent);
1000
procedure RegisterBeforeUtf8KeyPressHandler(AHandlerProc: TUTF8KeyPressEvent);
1001
procedure UnregisterBeforeUtf8KeyPressHandler(AHandlerProc: TUTF8KeyPressEvent);
832
1003
function SearchReplace(const ASearch, AReplace: string;
833
1004
AOptions: TSynSearchOptions): integer;
834
1005
function SearchReplaceEx(const ASearch, AReplace: string;
835
1006
AOptions: TSynSearchOptions; AStart: TPoint): integer;
837
Procedure SetHighlightSearch(const ASearch: String; AOptions: TSynSearchOptions);
838
procedure SelectToBrace;
839
procedure SetSelWord; deprecated;
840
procedure SelectWord;
841
procedure SelectLine(WithLeadSpaces: Boolean = True);
842
procedure SelectParagraph;
843
1008
procedure SetUseIncrementalColor(const AValue : Boolean);
844
procedure SetBookMark(BookMark: Integer; X: Integer; Y: Integer);
845
1009
procedure SetDefaultKeystrokes; virtual;
1010
procedure ResetMouseActions; // set mouse-actions according to current Options / may clear them
846
1011
procedure SetOptionFlag(Flag: TSynEditorOption; Value: boolean);
848
function GetLineState(ALine: Integer): TSynLineState;
1012
Procedure SetHighlightSearch(const ASearch: String; AOptions: TSynSearchOptions);
849
1013
{$IFDEF SYN_COMPILER_4_UP}
850
1014
function UpdateAction(TheAction: TBasicAction): boolean; override;
852
1016
procedure WndProc(var Msg: TMessage); override;
1017
procedure EraseBackground(DC: HDC); override;
854
procedure InsertTextAtCaret(aText: String; aCaretMode : TSynCaretAdjustMode = scamEnd);
855
property BlockBegin: TPoint read GetBlockBegin write SetBlockBegin; // Set Blockbegin. For none persistent also sets Blockend. Setting Caret may undo this and should be done before setting block
856
property BlockEnd: TPoint read GetBlockEnd write SetBlockEnd;
1019
procedure FindMatchingBracket; virtual;
1020
function FindMatchingBracket(PhysStartBracket: TPoint;
1021
StartIncludeNeighborChars, MoveCaret,
1022
SelectBrackets, OnlyVisible: Boolean
1025
procedure CodeFoldAction(iLine: integer); deprecated;
1026
procedure UnfoldAll;
1027
procedure FoldAll(StartLevel : Integer = 0; IgnoreNested : Boolean = False);
857
1028
property FoldState: String read GetFoldState write SetFoldState;
858
property CanPaste: Boolean read GetCanPaste;
859
property CanRedo: boolean read GetCanRedo;
860
property CanUndo: boolean read GetCanUndo;
861
property CaretX: Integer read GetCaretX write SetCaretX;
862
property CaretY: Integer read GetCaretY write SetCaretY;
863
property CaretXY: TPoint read GetCaretXY write SetCaretXY;// screen position
864
property LogicalCaretXY: TPoint read GetLogicalCaretXY write SetLogicalCaretXY;
865
property CharsInWindow: Integer read fCharsInWindow;
866
property CharWidth: integer read fCharWidth;
867
property Color default clWhite;
868
property Beautifier: TSynCustomBeautifier read fBeautifier write SetBeautifier;
870
property CtrlMouseActive: boolean read fCtrlMouseActive; deprecated; // deprecated in 0.9.29
873
property SelStart: Integer read GetSelStart write SetSelStart;
874
property SelEnd: Integer read GetSelEnd write SetSelEnd;
875
property UseIncrementalColor : Boolean write SetUseIncrementalColor;
877
property GutterWidth: Integer read GetGutterWidth; deprecated; // deprecated in 0.9.29 (08/2010)
878
property Highlighter: TSynCustomHighlighter
879
read fHighlighter write SetHighlighter;
880
property LeftChar: Integer read fLeftChar write SetLeftChar;
881
property LineHeight: integer read fTextHeight;
882
property LinesInWindow: Integer read fLinesInWindow; // MG: fully visible lines
883
property LineText: string read GetLineText write SetLineText;
884
property Text: string read SynGetText write SynSetText; // No uncommited (trailing/trimmable) spaces
885
property Marks: TSynEditMarkList read fMarkList;
1030
procedure AddKey(Command: TSynEditorCommand; Key1: word; SS1: TShiftState;
1031
Key2: word; SS2: TShiftState);
1033
property CharsInWindow: Integer read GetCharsInWindow;
1034
property CharWidth: integer read GetCharWidth;
1035
property LeftChar: Integer read GetLeftChar write SetLeftChar;
1036
property LineHeight: integer read GetLineHeight;
1037
property LinesInWindow: Integer read GetLinesInWindow;
886
1038
property MaxLeftChar: integer read fMaxLeftChar write SetMaxLeftChar
1040
property TopLine: Integer read GetTopLine write SetTopLine;
1042
property UseIncrementalColor : Boolean write SetUseIncrementalColor;
888
1043
property Modified: Boolean read GetModified write SetModified;
889
1044
property PaintLock: Integer read fPaintLock;
890
property ReadOnly: Boolean read GetReadOnly write SetReadOnly default FALSE;
891
property SelAvail: Boolean read GetSelAvail;
892
property SelText: string read GetSelText write SetSelTextExternal;
894
property TextBetweenPoints[aStartPoint, aEndPoint: TPoint]: String
895
read GetTextBetweenPoints write SetTextBetweenPoints;
896
property TextBetweenPointsEx[aStartPoint, aEndPoint: TPoint; CaretMode: TSynCaretAdjustMode]: String
897
write SetTextBetweenPointsEx;
898
property TopLine: Integer read fTopLine write SetTopLine;
900
1046
property UseUTF8: boolean read FUseUTF8;
901
procedure Update; override;
902
1047
procedure Invalidate; override;
903
1048
property ChangeStamp: int64 read GetChangeStamp;
905
1049
procedure ShareTextBufferFrom(AShareEditor: TCustomSynEdit);
906
1050
procedure UnShareTextBuffer;
910
property OnProcessCommand: TProcessCommandEvent
911
read FOnProcessCommand write FOnProcessCommand;
912
1052
function PluginCount: Integer;
913
property Plugin[Index: Integer]: TSynEditPlugin read GetPlugin;
1053
property Plugin[Index: Integer]: TLazSynEditPlugin read GetPlugin;
914
1054
function MarkupCount: Integer;
915
1055
property Markup[Index: integer]: TSynEditMarkup read GetMarkup;
916
1056
property MarkupByClass[Index: TSynEditMarkupClass]: TSynEditMarkup
917
1057
read GetMarkupByClass;
918
1058
property TrimSpaceType: TSynEditStringTrimmingType
919
1059
read GetTrimSpaceType write SetTrimSpaceType;
921
property BookMarkOptions: TSynBookMarkOpt
922
read fBookMarkOpt write fBookMarkOpt;
923
property BlockIndent: integer read fBlockIndent write SetBlockIndent default 2;
924
property ExtraCharSpacing: integer
925
read fExtraCharSpacing write SetExtraCharSpacing default 0;
926
property ExtraLineSpacing: integer
927
read fExtraLineSpacing write SetExtraLineSpacing default 0;
1062
property InsertCaret: TSynEditCaretType read FInsertCaret write SetInsertCaret default ctVerticalLine;
1063
property OverwriteCaret: TSynEditCaretType read FOverwriteCaret write SetOverwriteCaret default ctBlock;
1066
property HideSelection: boolean read fHideSelection write SetHideSelection default false;
1067
property DefaultSelectionMode: TSynSelectionMode read GetDefSelectionMode write SetDefSelectionMode default smNormal;
1068
property SelectionMode: TSynSelectionMode read GetSelectionMode write SetSelectionMode default smNormal;
1069
property SelectedColor: TSynSelectedColor read GetSelectedColor write SetSelectedColor;
1072
property Color default clWhite;
1073
property IncrementColor: TSynSelectedColor read GetIncrementColor write SetIncrementColor;
1074
property HighlightAllColor: TSynSelectedColor read GetHighlightAllColor write SetHighlightAllColor;
1075
property BracketMatchColor: TSynSelectedColor read GetBracketMatchColor write SetBracketMatchColor;
1076
property MouseLinkColor: TSynSelectedColor read GetMouseLinkColor write SetMouseLinkColor;
1077
property LineHighlightColor: TSynSelectedColor read GetLineHighlightColor write SetLineHighlightColor;
1078
property FoldedCodeColor: TSynSelectedColor read GetFoldedCodeColor write SetFoldedCodeColor;
1080
property Beautifier: TSynCustomBeautifier read fBeautifier write SetBeautifier;
1081
property BookMarkOptions: TSynBookMarkOpt read fBookMarkOpt write fBookMarkOpt;
1082
property BlockIndent: integer read FBlockIndent write SetBlockIndent default 2;
1083
property BlockTabIndent: integer read FBlockTabIndent write SetBlockTabIndent default 0;
1084
property ExtraCharSpacing: integer read fExtraCharSpacing write SetExtraCharSpacing default 0;
1085
property ExtraLineSpacing: integer read fExtraLineSpacing write SetExtraLineSpacing default 0;
1086
property Highlighter: TSynCustomHighlighter read fHighlighter write SetHighlighter;
928
1087
property Gutter: TSynGutter read FLeftGutter write SetGutter;
929
1088
property RightGutter: TSynGutter read FRightGutter write SetRightGutter;
930
property HideSelection: boolean read fHideSelection write SetHideSelection
932
property InsertCaret: TSynEditCaretType read FInsertCaret
933
write SetInsertCaret default ctVerticalLine;
934
1089
property InsertMode: boolean read fInserting write SetInsertMode
936
1091
property Keystrokes: TSynEditKeyStrokes
937
1092
read FKeystrokes write SetKeystrokes;
938
1093
property MouseActions: TSynEditMouseActions
939
read FMouseActions write SetMouseActions;
1094
read GetMouseActions write SetMouseActions;
1095
property MouseTextActions: TSynEditMouseActions
1096
read GetMouseTextActions write SetMouseTextActions;
940
1097
property MouseSelActions: TSynEditMouseActions // Mouseactions, if mouse is over selection => fallback to normal
941
read FMouseSelActions write SetMouseSelActions;
1098
read GetMouseSelActions write SetMouseSelActions;
942
1099
property MaxUndo: Integer read GetMaxUndo write SetMaxUndo default 1024;
943
property Options: TSynEditorOptions read fOptions write SetOptions // See SYNEDIT_UNIMPLEMENTED_OPTIONS for deprecated Values
1100
property Options: TSynEditorOptions read FOptions write SetOptions // See SYNEDIT_UNIMPLEMENTED_OPTIONS for deprecated Values
944
1101
default SYNEDIT_DEFAULT_OPTIONS;
945
property Options2: TSynEditorOptions2 read fOptions2 write SetOptions2
1102
property Options2: TSynEditorOptions2 read FOptions2 write SetOptions2
946
1103
default SYNEDIT_DEFAULT_OPTIONS2;
1104
property MouseOptions: TSynEditorMouseOptions read FMouseOptions write SetMouseOptions
1105
default SYNEDIT_DEFAULT_MOUSE_OPTIONS;
947
1106
property ShareOptions: TSynEditorShareOptions read FShareOptions write SetShareOptions
948
1107
default SYNEDIT_DEFAULT_SHARE_OPTIONS; experimental;
949
property OverwriteCaret: TSynEditCaretType read FOverwriteCaret
950
write SetOverwriteCaret default ctBlock;
951
property RightEdge: Integer read fRightEdge write SetRightEdge default 80;
952
property RightEdgeColor: TColor
953
read fRightEdgeColor write SetRightEdgeColor default clSilver;
1108
property VisibleSpecialChars: TSynVisibleSpecialChars read FVisibleSpecialChars write SetVisibleSpecialChars;
1109
property ReadOnly: Boolean read GetReadOnly write SetReadOnly default FALSE;
1110
property RightEdge: Integer read GetRightEdge write SetRightEdge default 80;
1111
property RightEdgeColor: TColor read GetRightEdgeColor write SetRightEdgeColor default clSilver;
954
1112
property ScrollBars: TScrollStyle
955
1113
read FScrollBars write SetScrollBars default ssBoth;
956
property SelectedColor: TSynSelectedColor
957
read GetSelectedColor write SetSelectedColor; // Setter for compatibility
958
property IncrementColor: TSynSelectedColor read GetIncrementColor;
959
property HighlightAllColor: TSynSelectedColor read GetHighlightAllColor;
960
property BracketMatchColor: TSynSelectedColor read GetBracketMatchColor;
961
property MouseLinkColor: TSynSelectedColor read GetMouseLinkColor;
962
property LineHighlightColor: TSynSelectedColor read GetLineHighlightColor;
963
property FoldedCodeColor: TSynSelectedColor read GetFoldedCodeColor;
964
1114
property BracketHighlightStyle: TSynEditBracketHighlightStyle
965
1115
read GetBracketHighlightStyle write SetBracketHighlightStyle;
966
property DefaultSelectionMode: TSynSelectionMode
967
read GetDefSelectionMode write SetDefSelectionMode default smNormal;
968
property SelectionMode: TSynSelectionMode
969
read GetSelectionMode write SetSelectionMode default smNormal;
970
// See Highlighter for new methods
971
property CFDividerDrawLevel: Integer
972
read GetDividerDrawLevel write SetDividerDrawLevel; deprecated;
973
1116
property TabWidth: integer read fTabWidth write SetTabWidth default 8;
974
property WantTabs: boolean read fWantTabs write SetWantTabs default FALSE;
1117
property WantTabs: boolean read fWantTabs write SetWantTabs default True;
975
1120
property OnChange: TNotifyEvent read FOnChange write FOnChange;
976
1121
property OnChangeUpdating: TChangeUpdatingEvent read FOnChangeUpdating write FOnChangeUpdating;
977
1122
property OnCutCopy: TSynCopyPasteEvent read FOnCutCopy write FOnCutCopy;
978
1123
property OnPaste: TSynCopyPasteEvent read FOnPaste write FOnPaste;
979
property OnCommandProcessed: TProcessCommandEvent
980
read fOnCommandProcessed write fOnCommandProcessed;
981
1124
property OnDropFiles: TSynDropFilesEvent read fOnDropFiles write fOnDropFiles;
982
property OnGutterClick: TGutterClickEvent
983
read GetOnGutterClick write SetOnGutterClick;
1125
property OnGutterClick: TGutterClickEvent read GetOnGutterClick write SetOnGutterClick;
984
1126
property OnPaint: TPaintEvent read fOnPaint write fOnPaint;
985
1127
// OnPlaceBookmark only triggers for Bookmarks
986
1128
property OnPlaceBookmark: TPlaceMarkEvent read FOnPlaceMark write FOnPlaceMark;
987
1129
// OnClearBookmark only triggers for Bookmarks
988
1130
property OnClearBookmark: TPlaceMarkEvent read FOnClearMark write FOnClearMark;
989
property OnProcessUserCommand: TProcessCommandEvent
990
read FOnProcessUserCommand write FOnProcessUserCommand;
991
property OnReplaceText: TReplaceTextEvent read fOnReplaceText
992
write fOnReplaceText;
994
property OnSpecialLineColors: TSpecialLineColorsEvent
995
read FOnSpecialLineColors write SetSpecialLineColors; deprecated;
997
property OnSpecialLineColors: TSpecialLineColorsEvent
998
read fOnSpecialLineColors write fOnSpecialLineColors;
1000
{$IFDEF SYN_LAZARUS}
1001
property OnSpecialLineMarkup: TSpecialLineMarkupEvent
1002
read FOnSpecialLineMarkup write SetSpecialLineMarkup;
1004
property OnStatusChange: TStatusChangeEvent
1005
read fOnStatusChange write fOnStatusChange;
1132
property OnKeyPress;
1133
property OnProcessCommand: TProcessCommandEvent read FOnProcessCommand write FOnProcessCommand;
1134
property OnProcessUserCommand: TProcessCommandEvent read FOnProcessUserCommand write FOnProcessUserCommand;
1135
property OnCommandProcessed: TProcessCommandEvent read fOnCommandProcessed write fOnCommandProcessed;
1136
property OnReplaceText: TReplaceTextEvent read fOnReplaceText write fOnReplaceText;
1137
property OnSpecialLineColors: TSpecialLineColorsEvent read FOnSpecialLineColors write SetSpecialLineColors; deprecated;
1138
property OnSpecialLineMarkup: TSpecialLineMarkupEvent read FOnSpecialLineMarkup write SetSpecialLineMarkup;
1139
property OnStatusChange: TStatusChangeEvent read fOnStatusChange write fOnStatusChange;
1008
1142
TSynEdit = class(TCustomSynEdit)
1010
property ShareOptions;
1012
1144
// inherited properties
1013
1145
property Align;
1014
1146
property Beautifier;
1015
1147
property BlockIndent;
1148
property BlockTabIndent;
1016
1149
property BorderSpacing;
1017
{$IFNDEF SYN_LAZARUS}
1019
property ParentCtl3D;
1021
1150
{$IFDEF SYN_COMPILER_4_UP}
1022
1151
property Anchors;
1023
1152
property Constraints;
1025
1154
property Color;
1026
{$IFDEF SYN_LAZARUS}
1027
1155
property Cursor default crIBeam;
1029
1156
property Enabled;
1031
1158
property Height;
2268
2564
procedure TCustomSynEdit.InvalidateGutterLines(FirstLine, LastLine: integer); // Todo: move to gutter
2271
2566
TopFoldLine: LongInt;
2273
2568
if sfPainting in fStateFlags then exit;
2274
if Visible and HandleAllocated then
2569
if Visible and HandleAllocated then begin
2570
{$IFDEF VerboseSynEditInvalidate}
2571
DebugLnEnter(['TCustomSynEdit.InvalidateGutterLines ',DbgSName(self), ' FirstLine=',FirstLine, ' LastLine=',LastLine]);
2275
2573
if (FirstLine = -1) and (LastLine = -1) then begin
2276
if FLeftGutter.Visible then begin;
2277
rcInval := Rect(0, 0, FLeftGutter.Width, ClientHeight - ScrollBarWidth);
2278
{$IFDEF VerboseSynEditInvalidate}
2279
DebugLn(['TCustomSynEdit.InvalidateGutterLines ',DbgSName(self),' ALL ',dbgs(rcInval)]);
2281
InvalidateRect(Handle, @rcInval, FALSE);
2284
if FRightGutter.Visible then begin
2285
rcInval := Rect(ClientWidth - FRightGutter.Width - ScrollBarWidth, 0,
2286
ClientWidth - ScrollBarWidth, ClientHeight - ScrollBarWidth);
2287
{$IFDEF VerboseSynEditInvalidate}
2288
DebugLn(['TCustomSynEdit.InvalidateGutterLines ',DbgSName(self),' ALL ',dbgs(rcInval)]);
2290
InvalidateRect(Handle, @rcInval, FALSE);
2574
FPaintArea.InvalidateGutterLines(-1, -1);
2293
2576
// pretend we haven't scrolled
2294
2577
TopFoldLine := FFoldedLinesView.TopLine;
2295
if FOldTopLine <> FTopLine then
2296
FFoldedLinesView.TopTextIndex := FOldTopLine - 1;
2298
{ find the visible lines first }
2299
if LastLine >= 0 then begin
2300
if (LastLine < FirstLine) then SwapInt(LastLine, FirstLine);
2301
LastLine := RowToScreenRow(Min(LastLine, ScreenRowToRow(LinesInWindow)))+1;
2302
LastLine := LastLine;
2305
LastLine := LinesInWindow + 1;
2306
FirstLine := RowToScreenRow(Max(FirstLine, TopLine));
2307
FirstLine := Max(0, FirstLine);
2308
{ any line visible? }
2309
if (LastLine >= FirstLine) then begin
2310
if FLeftGutter.Visible then begin;
2311
rcInval := Rect(0, fTextHeight * FirstLine,
2312
FLeftGutter.Width, fTextHeight * LastLine);
2313
{$IFDEF VerboseSynEditInvalidate}
2314
DebugLn(['TCustomSynEdit.InvalidateGutterLines ',DbgSName(self),' PART ',dbgs(rcInval)]);
2316
InvalidateRect(Handle, @rcInval, FALSE);
2319
if FRightGutter.Visible then begin
2320
rcInval.Left := ClientWidth - FRightGutter.Width - ScrollBarWidth;
2321
rcInval.Right := ClientWidth - ScrollBarWidth;
2322
{$IFDEF VerboseSynEditInvalidate}
2323
DebugLn(['TCustomSynEdit.InvalidateGutterLines ',DbgSName(self),' PART ',dbgs(rcInval)]);
2325
InvalidateRect(Handle, @rcInval, FALSE);
2578
if FOldTopView <> TopView then
2579
FFoldedLinesView.TopLine := FOldTopView;
2581
if (LastLine <> -1) and (LastLine < FirstLine) then
2582
SwapInt(FirstLine, LastLine);
2584
FPaintArea.InvalidateGutterLines(FirstLine-1, LastLine-1);
2329
2586
FFoldedLinesView.TopLine := TopFoldLine;
2588
{$IFDEF VerboseSynEditInvalidate}
2589
DebugLnExit(['TCustomSynEdit.InvalidateGutterLines ',DbgSName(self)]);
2333
2594
procedure TCustomSynEdit.InvalidateLines(FirstLine, LastLine: integer);
2337
2596
TopFoldLine: LongInt;
2339
2598
if sfPainting in fStateFlags then exit;
2340
if Visible and HandleAllocated then
2599
if Visible and HandleAllocated then begin
2600
{$IFDEF VerboseSynEditInvalidate}
2601
DebugLnEnter(['TCustomSynEdit.InvalidateTextLines ',DbgSName(self), ' FirstLine=',FirstLine, ' LastLine=',LastLine]);
2341
2603
if (FirstLine = -1) and (LastLine = -1) then begin
2342
rcInval := ClientRect;
2343
rcInval.Left := TextLeftPixelOffset(False);
2344
rcInval.Right := ClientWidth - TextRightPixelOffset - ScrollBarWidth;
2345
{$IFDEF VerboseSynEditInvalidate}
2346
DebugLn(['TCustomSynEdit.InvalidateLines ',DbgSName(self),' ALL ',dbgs(rcInval)]);
2348
InvalidateRect(Handle, @rcInval, FALSE);
2604
FPaintArea.InvalidateTextLines(-1, -1);
2350
2606
// pretend we haven't scrolled
2351
2607
TopFoldLine := FFoldedLinesView.TopLine;
2352
if FOldTopLine <> FTopLine then
2353
FFoldedLinesView.TopTextIndex := FOldTopLine - 1;
2355
{ find the visible lines first }
2356
if LastLine >= 0 then begin
2357
if (LastLine < FirstLine) then SwapInt(LastLine, FirstLine);
2358
l := RowToScreenRow(Min(LastLine, ScreenRowToRow(LinesInWindow)))+1;
2362
l := LinesInWindow + 1;
2363
f := RowToScreenRow(Max(FirstLine, TopLine));
2365
{ any line visible? }
2366
if (l >= f) then begin
2367
rcInval := Rect(TextLeftPixelOffset(False), fTextHeight * f,
2368
ClientWidth - TextRightPixelOffset - ScrollBarWidth, fTextHeight * l);
2369
{$IFDEF VerboseSynEditInvalidate}
2370
DebugLn(['TCustomSynEdit.InvalidateLines ',DbgSName(self),' PART ',dbgs(rcInval)]);
2372
InvalidateRect(Handle, @rcInval, FALSE);
2608
if FOldTopView <> TopView then
2609
FFoldedLinesView.TopLine := FOldTopView;
2611
if (LastLine <> -1) and (LastLine < FirstLine) then
2612
SwapInt(FirstLine, LastLine);
2614
FPaintArea.InvalidateTextLines(FirstLine-1, LastLine-1);
2375
2616
FFoldedLinesView.TopLine := TopFoldLine;
2618
{$IFDEF VerboseSynEditInvalidate}
2619
DebugLnExit(['TCustomSynEdit.InvalidateTextLines ',DbgSName(self)]);
2379
2624
procedure TCustomSynEdit.KeyDown(var Key: Word; Shift: TShiftState);
3173
procedure TCustomSynEdit.PaintTextLines(AClip: TRect; FirstLine, LastLine,
3174
FirstCol, LastCol: integer);
3175
// FirstLine, LastLine are based 1
3176
// FirstCol, LastCol are screen based 1 without scrolling (physical position).
3177
// i.e. the real screen position is fTextOffset+Pred(FirstCol)*CharWidth
3179
bDoRightEdge: boolean; // right edge
3180
nRightEdge: integer;
3181
colEditorBG: TColor;
3182
// painting the background and the text
3183
rcLine, rcToken: TRect;
3184
EraseLeft, DrawLeft: Integer; // LeftSide for EraseBackground, Text
3185
CurLine: integer; // Screen-line index for the loop
3186
CurTextIndex: Integer; // Current Index in text
3187
CurPhysPos, CurLogIndex : Integer; // Physical Start Position of next token in current Line
3190
Len, MaxLen: integer;
3191
PhysicalStartPos, PhysicalEndPos: integer;
3195
FrameColor: array[TSynFrameSide] of TColor;
3196
FrameStyle: array[TSynFrameSide] of TSynLineStyle;
3200
ExpandedPaintToken: string; // used to create the string sent to TextDrawer
3201
CharWidths: TPhysicalCharWidths;
3203
{ local procedures }
3205
procedure SetTokenAccuLength;
3207
ReAllocMem(TokenAccu.p,TokenAccu.MaxLen+1);
3208
TokenAccu.p[TokenAccu.MaxLen]:=#0;
3211
function ExpandSpecialChars(var p: PChar; var Count: integer;
3212
PhysicalStartPos: integer): Integer;
3213
// if there are no tabs or special chars: keep p and Count untouched
3214
// if there are special chars: copy p into ExpandedPaintToken buffer,
3215
// convert tabs to spaces, and return the buffer
3216
// Return DisplayCell-Count in Buffer
3219
LengthNeeded: Integer;
3225
Special, HasTabs: boolean;
3232
for i := CurLogIndex to CurLogIndex + Count -1 do begin
3233
Result := Result + CharWidths[i];
3234
if CharWidths[i] > 1 then
3235
LengthNeeded := LengthNeeded + CharWidths[i] - 1;
3236
if p[SrcPos] = #9 then HasTabs := True;
3239
Special:=eoShowSpecialChars in Options;
3240
if (not Special) and (LengthNeeded=0) and (not HasTabs)
3241
and (FindInvalidUTF8Character(p,Count)<0) then
3243
LengthNeeded := LengthNeeded + Count;
3244
if Special then LengthNeeded:=LengthNeeded*2;
3245
if length(ExpandedPaintToken)<LengthNeeded then
3246
SetLength(ExpandedPaintToken,LengthNeeded+CharsInWindow);
3247
//DebugLn(['ExpandSpecialChars Count=',Count,' TabCount=',TabCount,' Special=',Special,' LengthNeeded=',LengthNeeded]);
3250
Dest:=PChar(Pointer(ExpandedPaintToken));
3251
if UseUTF8 then begin
3252
while SrcPos<Count do begin
3254
Fill := CharWidths[CurLogIndex + SrcPos] - 1;
3255
if c = #9 then begin
3256
// tab char, fill spaces at start
3257
for i := 0 to Fill do begin
3258
Dest[DestPos]:= ' ';
3261
if Special then begin
3262
// #194#187 looks like >>
3263
Dest[DestPos-1] := #194;
3264
Dest[DestPos] := #187;
3270
// could be UTF8 char
3271
if c in [#128..#255]
3272
then CharLen := UTF8CharacterStrictLength(@p[SrcPos])
3274
if CharLen=0 then begin
3275
// invalid character
3280
// normal UTF-8 character
3281
for i:=1 to CharLen do begin
3282
Dest[DestPos]:=p[SrcPos];
3286
if (c = #32) and Special then begin
3287
// #194#183 looks like .
3288
Dest[DestPos-1] := #194;
3289
Dest[DestPos] := #183;
3292
for i := 1 to Fill do begin
3293
Dest[DestPos]:= ' ';
3297
// ToDo: pass the eto with to fTextDrawer, instead of filling with spaces
3298
if Fill > 0 then ForceEto := True;
3303
while SrcPos<Count do begin
3305
Fill := CharWidths[CurLogIndex + SrcPos] - 1;
3306
if c = #9 then // tab char
3307
Dest[DestPos] := ' '
3309
Dest[DestPos] := p[SrcPos];
3310
if Fill > 0 then ForceEto := True;
3314
for i := 1 to Fill do begin
3315
Dest[DestPos]:= ' ';
3320
p:=PChar(Pointer(ExpandedPaintToken));
3322
//debugln('ExpandSpecialChars Token with Tabs: "',DbgStr(copy(ExpandedPaintToken,1,Count)),'"');
3326
ETOOptions = ETO_OPAQUE; // Note: clipping is slow and not needed
3328
procedure PaintToken(Token: PChar; TokenLen, FirstPhysical: integer);
3329
// FirstPhysical is the physical (screen without scrolling)
3330
// column of the first character
3335
{debugln('PaintToken A TokenLen=',dbgs(TokenLen),
3336
' FirstPhysical=',dbgs(FirstPhysical),
3337
' Tok="'+copy(Token, 1, TokenLen),'"',
3338
' rcToken='+dbgs(rcToken.Left)+'-'+dbgs(rcToken.Right));}
3339
if (rcToken.Right <= rcToken.Left) then exit;
3340
// Draw the right edge under the text if necessary
3341
nX := ScreenColumnToXValue(FirstPhysical); // == rcToken.Left
3342
if ForceEto then fTextDrawer.ForceNextTokenWithEto;
3343
if bDoRightEdge and (not (eoHideRightMargin in Options))
3344
and (nRightEdge<rcToken.Right) and (nRightEdge>=rcToken.Left)
3346
// draw background (use rcToken, so we do not delete the divider-draw-line)
3347
if rcToken.Left < nRightEdge then begin
3349
tok.Right := nRightEdge;
3350
InternalFillRect(dc, tok);
3352
if rcToken.Right > nRightEdge then begin
3354
tok.Left := nRightEdge;
3355
tok.Bottom := rcLine.Bottom;
3356
InternalFillRect(dc, tok);
3358
// draw edge (use rcLine / rcToken may be reduced)
3359
LCLIntf.MoveToEx(dc, nRightEdge, rcLine.Top, nil);
3360
LCLIntf.LineTo(dc, nRightEdge, rcLine.Bottom + 1);
3362
fTextDrawer.ExtTextOut(nX, rcToken.Top, ETOOptions-ETO_OPAQUE, rcToken,
3363
Token, TokenLen, rcLine.Bottom);
3365
// draw text with background
3366
//debugln('PaintToken nX=',dbgs(nX),' Token=',dbgstr(copy(Token,1, TokenLen)),' rcToken=',dbgs(rcToken));
3368
if rcToken.Right > nRightEdge + 1 then
3369
tok.Bottom := rcLine.Bottom;
3370
fTextDrawer.ExtTextOut(nX, rcToken.Top, ETOOptions, tok,
3371
Token, TokenLen, rcLine.Bottom);
3373
rcToken.Left := rcToken.Right;
3376
procedure PaintHighlightToken(bFillToEOL: boolean);
3380
MarkupInfo, FoldedCodeInfo: TSynSelectedColor;
3381
FillFCol, FillBCol, FillFrame: TColor;
3382
FrameStyle: TSynLineStyle;
3383
FillStyle: TFontStyles;
3385
Attr: TSynHighlighterAttributes;
3387
side: TSynFrameSide;
3389
{debugln('PaintHighlightToken A TokenAccu: Len=',dbgs(TokenAccu.Len),
3390
' PhysicalStartPos=',dbgs(TokenAccu.PhysicalStartPos),
3391
' PhysicalEndPos=',dbgs(TokenAccu.PhysicalEndPos),
3392
' "',copy(TokenAccu.p,1,TokenAccu.Len),'"');}
3394
// Any token chars accumulated?
3395
if (TokenAccu.Len > 0) then
3397
// Initialize the colors and the font style.
3400
SetBackColor(TokenAccu.BG);
3401
SetForeColor(TokenAccu.FG);
3402
SetStyle(TokenAccu.Style);
3403
for s := low(TSynFrameSide) to high(TSynFrameSide) do begin
3404
FrameColor[s] := TokenAccu.FrameColor[s];
3405
FrameStyle[s] := TokenAccu.FrameStyle[s];
3409
rcToken.Right := ScreenColumnToXValue(TokenAccu.PhysicalEndPos+1);
3410
if rcToken.Right > AClip.Right then begin
3411
rcToken.Right := AClip.Right;
3412
fTextDrawer.FrameColor[sfdRight] := clNone; // right side of char is not painted
3414
with TokenAccu do PaintToken(p, Len, PhysicalStartPos);
3417
// Fill the background to the end of this line if necessary.
3418
if bFillToEOL and (rcToken.Left < rcLine.Right) then begin
3419
eolx := rcToken.Left; // remeber end of actual line, so we can decide to draw the right edge
3420
NextPos := Min(LastCol, TokenAccu.PhysicalEndPos+1);
3421
if Assigned(fHighlighter) then
3422
Attr := fHighlighter.GetEndOfLineAttribute
3426
MarkupInfo := fMarkupManager.GetMarkupAttributeAtRowCol(FFoldedLinesView.TextIndex[CurLine]+1, NextPos);
3427
NextPos := fMarkupManager.GetNextMarkupColAfterRowCol(FFoldedLinesView.TextIndex[CurLine]+1, NextPos);
3429
if Assigned(Attr) then
3431
FillFCol := Attr.Foreground;
3432
FillBCol := Attr.Background;
3433
FillFrame := Attr.FrameColor;
3434
FillStyle := Attr.Style;
3435
FrameStyle := Attr.FrameStyle;
3436
if FillFCol = clNone then FillFCol := Font.Color;
3437
if FillBCol = clNone then FillBCol := colEditorBG;
3440
FillFCol := Font.Color;
3441
FillBCol := colEditorBG;
3442
FillFrame := clNone;
3443
FillStyle := Font.Style;
3444
FrameStyle := slsSolid;
3447
if Assigned(MarkupInfo) then
3448
MarkupInfo.ModifyColors(FillFCol, FillBCol, FillFrame, FillStyle, FrameStyle);
3450
fTextDrawer.BackColor := FillBCol;
3451
//fTextDrawer.ForeColor := FillFCol; // for underline
3452
//fTextDrawer.Style := FillStyle;
3455
then nX1 := rcLine.Right
3457
nX1 := ScreenColumnToXValue(NextPos);
3458
if nX1 > rcLine.Right
3459
then nX1 := rcLine.Right;
3462
if nX1 > nRightEdge then begin
3463
if rcToken.Left < nRightEdge then begin
3465
tok.Right := nRightEdge;
3466
InternalFillRect(dc, tok);
3467
rcToken.Left := nRightEdge;
3469
rcToken.Bottom := rcLine.Bottom;
3471
rcToken.Right := nX1;
3472
InternalFillRect(dc, rcToken); {TODO: if style underline, then print spaces}
3473
rcToken.Left := nX1;
3474
until nX1 >= rcLine.Right;
3476
// Draw the right edge if necessary.
3477
if bDoRightEdge and (not (eoHideRightMargin in Options))
3478
and (nRightEdge >= eolx) then begin // xx rc Token
3479
LCLIntf.MoveToEx(dc, nRightEdge, rcLine.Top, nil);
3480
LCLIntf.LineTo(dc, nRightEdge, rcLine.Bottom + 1);
3483
if FFoldedLinesView.FoldType[CurLine] * [cfCollapsedFold, cfCollapsedHide] <> [] then
3485
FillFCol := Font.Color;
3486
FillBCol := colEditorBG;
3487
FillFrame := Font.Color;
3488
FrameStyle := slsSolid;
3490
MarkupInfo := fMarkupManager.GetMarkupAttributeAtRowCol(FFoldedLinesView.TextIndex[CurLine]+1, CurPhysPos + 3);
3491
if MarkupInfo <> nil then
3492
MarkupInfo.ModifyColors(FillFCol, FillBCol, FillFrame, FillStyle, FrameStyle);
3493
FoldedCodeInfo := FoldedCodeColor;
3494
if Assigned(FoldedCodeInfo) then
3495
FoldedCodeInfo.ModifyColors(FillFCol, FillBCol, FillFrame, FillStyle, FrameStyle);
3496
if (FillBCol = FillFCol) then begin // or if diff(gb,fg) < x
3497
if FillBCol = colEditorBG
3498
then FillFCol := not(FillBCol) and $00ffffff // or maybe Font.color ?
3499
else FillFCol := colEditorBG;
3502
rcToken.Left := ScreenColumnToXValue(CurPhysPos+3);
3503
rcToken.Right := ScreenColumnToXValue(CurPhysPos+6);
3505
FTextDrawer.ForeColor := FillFCol;
3506
FTextDrawer.BackColor := FillBCol;
3507
FTextDrawer.SetStyle(FillStyle);
3509
if Assigned(FoldedCodeInfo) and (FoldedCodeInfo.FrameColor <> clNone) then
3511
for side := low(TSynFrameSide) to high(TSynFrameSide) do begin
3512
if ( (FoldedCodeInfo.FrameEdges = sfeAround) or
3513
((FoldedCodeInfo.FrameEdges = sfeBottom) and (side = sfdBottom)) or
3514
((FoldedCodeInfo.FrameEdges = sfeLeft) and (side = sfdLeft))
3517
FTextDrawer.FrameColor[side] := FoldedCodeInfo.FrameColor
3519
FTextDrawer.FrameColor[side] := clNone;
3520
FTextDrawer.FrameStyle[side] := FoldedCodeInfo.FrameStyle;
3523
if rcToken.Right > rcLine.Right then begin
3524
rcToken.Right := rcLine.Right;
3525
fTextDrawer.FrameColor[sfdRight] := clNone; // right side of char is not painted
3527
if rcToken.Right > rcToken.Left then begin
3528
if ForceEto then fTextDrawer.ForceNextTokenWithEto;
3529
fTextDrawer.ExtTextOut(rcToken.Left, rcToken.Top, ETOOptions-ETO_OPAQUE,
3530
rcToken, '...', 3, rcLine.Bottom);
3536
procedure AddHighlightToken(Token: PChar;
3537
TokenLen, PhysicalStartPos, PhysicalEndPos: integer;
3538
MarkupInfo : TSynSelectedColor);
3541
SpacesTest, IsSpaces: boolean;
3545
function TokenIsSpaces: boolean;
3550
if not SpacesTest then begin
3552
IsSpaces := not (eoShowSpecialChars in fOptions) ;
3553
pTok := PChar(Pointer(Token));
3555
while IsSpaces and (Cnt > 0) do begin
3556
if not (pTok^ in [' ',#9])
3557
then IsSpaces := False;
3566
{DebugLn('AddHighlightToken A TokenLen=',dbgs(TokenLen),
3567
' PhysicalStartPos=',dbgs(PhysicalStartPos),' PhysicalEndPos=',dbgs(PhysicalEndPos),
3568
' Tok="',copy(Token,1,TokenLen),'"');}
3570
// Do we have to paint the old chars first, or can we just append?
3572
SpacesTest := FALSE;
3574
if (TokenAccu.Len > 0) then
3577
// Frame can be continued
3578
(TokenAccu.FrameColor[sfdTop] = MarkupInfo.FrameSideColors[sfdTop]) and
3579
(TokenAccu.FrameStyle[sfdTop] = MarkupInfo.FrameSideStyles[sfdTop]) and
3580
(TokenAccu.FrameColor[sfdBottom] = MarkupInfo.FrameSideColors[sfdBottom]) and
3581
(TokenAccu.FrameStyle[sfdBottom] = MarkupInfo.FrameSideStyles[sfdBottom]) and
3582
(TokenAccu.FrameColor[sfdRight] = clNone) and
3583
(MarkupInfo.FrameSideColors[sfdLeft] = clNone) and
3585
(TokenAccu.BG = MarkupInfo.Background) and
3587
( ( (TokenAccu.FG = MarkupInfo.Foreground) and
3588
(TokenAccu.Style = MarkupInfo.Style)
3590
// whitechar only token, can ignore Foreground color and certain styles (yet must match underline)
3591
( (TokenAccu.Style - [fsBold, fsItalic] = MarkupInfo.Style - [fsBold, fsItalic]) and
3592
( (TokenAccu.Style * [fsUnderline, fsStrikeOut] = []) or
3593
(TokenAccu.FG = MarkupInfo.Foreground)
3598
// If we can't append it, then we have to paint the old token chars first.
3599
if not CanAppend then
3600
PaintHighlightToken(FALSE);
3603
// Don't use AppendStr because it's more expensive.
3604
//if (CurLine=TopLine) then debugln(' -t-Accu len ',dbgs(TokenAccu.Len),' pstart ',dbgs(TokenAccu.PhysicalStartPos),' p-end ',dbgs(TokenAccu.PhysicalEndPos));
3605
if CanAppend then begin
3606
if (TokenAccu.Len + TokenLen > TokenAccu.MaxLen) then begin
3607
TokenAccu.MaxLen := TokenAccu.Len + TokenLen + 32;
3611
for i := 0 to TokenLen-1 do begin
3612
TokenAccu.p[TokenAccu.Len + i] := Token[i];
3614
Inc(TokenAccu.Len, TokenLen);
3615
TokenAccu.PhysicalEndPos := PhysicalEndPos;
3616
TokenAccu.FrameColor[sfdRight] := MarkupInfo.FrameSideColors[sfdRight];
3617
TokenAccu.FrameStyle[sfdRight] := MarkupInfo.FrameSideStyles[sfdRight];
3619
TokenAccu.Len := TokenLen;
3620
if (TokenAccu.Len > TokenAccu.MaxLen) then begin
3621
TokenAccu.MaxLen := TokenAccu.Len + 32;
3624
for i := 0 to TokenLen-1 do begin
3625
TokenAccu.p[i] := Token[i];
3627
TokenAccu.PhysicalStartPos := PhysicalStartPos;
3628
TokenAccu.PhysicalEndPos := PhysicalEndPos;
3629
TokenAccu.FG := MarkupInfo.Foreground;
3630
TokenAccu.BG := MarkupInfo.Background;
3631
TokenAccu.Style := MarkupInfo.Style;
3632
for s := low(TSynFrameSide) to high(TSynFrameSide) do begin
3633
TokenAccu.FrameColor[s] := MarkupInfo.FrameSideColors[s];
3634
TokenAccu.FrameStyle[s] := MarkupInfo.FrameSideStyles[s];
3637
{debugln('AddHighlightToken END CanAppend=',dbgs(CanAppend),
3638
' Len=',dbgs(TokenAccu.Len),
3639
' PhysicalStartPos=',dbgs(TokenAccu.PhysicalStartPos),
3640
' PhysicalEndPos=',dbgs(TokenAccu.PhysicalEndPos),
3641
' "',copy(TokenAccu.s,1,TokenAccu.Len),'"');}
3644
procedure DrawHiLightMarkupToken(attr: TSynHighlighterAttributes;
3645
sToken: PChar; nTokenByteLen: integer);
3647
DefaultFGCol, DefaultBGCol: TColor;
3648
PhysicalStartPos: integer;
3649
PhysicalEndPos: integer;
3651
SubTokenByteLen, SubCharLen, TokenCharLen : Integer;
3652
NextPhysPos : Integer;
3654
function CharToByteLen(aCharLen: Integer) : Integer;
3656
if not UseUTF8 then exit(aCharLen);
3657
Result := UTF8CharToByteIndex(sToken, nTokenByteLen, aCharLen);
3658
if Result < 0 then begin
3659
debugln('ERROR: Could not convert CharLen (',dbgs(aCharLen),') to byteLen (maybe invalid UTF8?)',' len ',dbgs(nTokenByteLen),' Line ',dbgs(CurLine),' PhysPos ',dbgs(CurPhysPos));
3664
procedure InitTokenColors;
3666
FPaintLineColor.Clear;
3667
if Assigned(attr) then
3669
DefaultFGCol := attr.Foreground;
3670
DefaultBGCol := attr.Background;
3671
if DefaultBGCol = clNone then DefaultBGCol := colEditorBG;
3672
if DefaultFGCol = clNone then DefaultFGCol := Font.Color;
3674
FPaintLineColor.FrameColor := attr.FrameColor;
3675
FPaintLineColor.FrameStyle := attr.FrameStyle;
3676
FPaintLineColor.FrameEdges := attr.FrameEdges;
3677
FPaintLineColor.Style := attr.Style;
3678
// TSynSelectedColor.Style and StyleMask describe how to modify a style,
3679
// but FPaintLineColor contains an actual style
3680
FPaintLineColor.MergeFinalStyle := True;
3681
FPaintLineColor.StyleMask := [];
3682
if FPaintLineColor.Background = clNone then
3683
FPaintLineColor.Background := colEditorBG;
3684
if FPaintLineColor.Foreground = clNone then
3685
FPaintLineColor.Foreground := Font.Color;
3686
if attr.FrameColor <> clNone then begin
3687
FPaintLineColor.StartX := PhysicalStartPos;
3688
FPaintLineColor.EndX := PhysicalStartPos + TokenCharLen - 1;
3689
FPaintLineColor.MergeFrames(nil, PhysicalStartPos, PhysicalStartPos + TokenCharLen - 1);
3693
DefaultFGCol := Font.Color;
3694
DefaultBGCol := colEditorBG;
3695
FPaintLineColor.Style := Font.Style;
3698
FPaintLineColor.Foreground := DefaultFGCol;
3699
FPaintLineColor.Background := DefaultBGCol;
3703
if CurPhysPos > LastCol then exit;
3705
PhysicalStartPos := CurPhysPos;
3706
len := nTokenByteLen;
3707
TokenCharLen := ExpandSpecialChars(sToken, nTokenByteLen, PhysicalStartPos);
3708
CurLogIndex := CurLogIndex + len;
3709
// Prepare position for next token
3710
inc(CurPhysPos, TokenCharLen);
3711
if CurPhysPos <= FirstCol then exit;
3713
// Remove any Part of the Token that is before FirstCol
3714
if PhysicalStartPos < FirstCol then begin
3715
SubCharLen := FirstCol - PhysicalStartPos;
3716
len := CharToByteLen(SubCharLen);
3717
dec(TokenCharLen, SubCharLen);
3718
inc(PhysicalStartPos, SubCharLen);
3719
dec(nTokenByteLen, len);
3723
// Remove any Part of the Token that is after LastCol
3724
SubCharLen := PhysicalStartPos + TokenCharLen - (LastCol + 1);
3725
if SubCharLen > 0 then begin
3726
dec(TokenCharLen, SubCharLen);
3727
nTokenByteLen := CharToByteLen(TokenCharLen);
3733
{TODO: cache NextPhysPos, and MarkupInfo between 2 calls }
3734
while (nTokenByteLen > 0) do begin
3735
FPaintLineColor2.Assign(FPaintLineColor);
3737
// Calculate Token Sublen for current Markup
3738
NextPhysPos := fMarkupManager.GetNextMarkupColAfterRowCol
3739
(FFoldedLinesView.TextIndex[CurLine]+1, PhysicalStartPos);
3741
then SubCharLen := TokenCharLen
3742
else SubCharLen := NextPhysPos - PhysicalStartPos;
3744
if SubCharLen > TokenCharLen then SubCharLen := TokenCharLen;
3745
if SubCharLen < 1 then begin // safety for broken input...
3746
debugln('ERROR: Got invalid SubCharLen ',dbgs(SubCharLen),' len ',dbgs(nTokenByteLen),' Line ',dbgs(CurLine),' PhysPos ',dbgs(CurPhysPos));
3750
SubTokenByteLen := CharToByteLen(SubCharLen);
3751
PhysicalEndPos:= PhysicalStartPos + SubCharLen - 1;
3754
fMarkupManager.MergeMarkupAttributeAtRowCol(FFoldedLinesView.TextIndex[CurLine]+1,
3755
PhysicalStartPos, PhysicalEndPos, FPaintLineColor2);
3757
// Deal with equal colors
3758
if (FPaintLineColor2.Background = FPaintLineColor2.Foreground) then begin // or if diff(gb,fg) < x
3759
if FPaintLineColor2.Background = DefaultBGCol then
3760
FPaintLineColor2.Foreground := not(FPaintLineColor2.Background) and $00ffffff // or maybe Font.color ?
3762
FPaintLineColor2.Foreground := DefaultBGCol;
3766
AddHighlightToken(sToken, SubTokenByteLen,
3767
PhysicalStartPos, PhysicalEndPos, FPaintLineColor2);
3769
PhysicalStartPos:=PhysicalEndPos + 1;
3770
dec(nTokenByteLen,SubTokenByteLen);
3771
dec(TokenCharLen, SubCharLen);
3772
inc(sToken, SubTokenByteLen);
3776
{$IFDEF SYNDEBUGPRINT}
3777
procedure DebugPrint(Txt: String; MinCol: Integer = 0);
3779
if CurPhysPos < MinCol then Txt := StringOfChar(' ', MinCol - CurPhysPos) + txt;
3780
Setlength(CharWidths, length(CharWidths) + length(Txt));
3781
FillChar(CharWidths[length(CharWidths)-length(Txt)], length(Txt), #1);
3782
DrawHiLightMarkupToken(nil, PChar(Pointer(Txt)), Length(Txt));
3786
procedure PaintLines;
3788
sLine: string; // the current line
3789
sToken: PChar; // highlighter token info
3790
nTokenLen: integer; // Pos in Char // Len in Byte ??
3791
attr: TSynHighlighterAttributes;
3793
DividerInfo: TSynDividerDrawConfigSetting;
3796
// Initialize rcLine for drawing. Note that Top and Bottom are updated
3797
// inside the loop. Get only the starting point for this.
3799
rcLine.Bottom := FirstLine * fTextHeight;
3800
// Make sure the token accumulator string doesn't get reassigned to often.
3801
if Assigned(fHighlighter) then begin
3802
TokenAccu.MaxLen := Max(128, fCharsInWindow * 4);
3806
// Now loop through all the lines. The indices are valid for Lines.
3807
CurLine := FirstLine-1;
3808
while CurLine<LastLine do begin
3810
CurTextIndex := FFoldedLinesView.TextIndex[CurLine];
3811
//CharWidths := FFoldedLinesView.GetPhysicalCharWidths(CurLine);
3812
CharWidths := FTheLinesView.GetPhysicalCharWidths(CurTextIndex);
3814
fMarkupManager.PrepareMarkupForRow(CurTextIndex+1);
3816
// Update the rcLine rect to this line.
3817
rcLine.Top := rcLine.Bottom;
3818
Inc(rcLine.Bottom, fTextHeight);
3819
// Paint the lines depending on the assigned highlighter.
3822
TokenAccu.PhysicalEndPos := FirstCol - 1; // in case of an empty line
3825
// Delete the whole Line
3826
fTextDrawer.BackColor := colEditorBG;
3827
SetBkColor(dc, ColorToRGB(colEditorBG));
3828
rcLine.Left := EraseLeft;
3829
InternalFillRect(dc, rcLine);
3830
rcLine.Left := DrawLeft;
3833
if not Assigned(fHighlighter) then begin
3834
sLine := FFoldedLinesView[CurLine];
3835
DrawHiLightMarkupToken(nil, PChar(Pointer(sLine)), Length(sLine));
3837
// draw splitter line
3838
DividerInfo := fHighlighter.DrawDivider[CurTextIndex];
3839
if (DividerInfo.Color <> clNone) and (nRightEdge > TextLeftPixelOffset(False) - 1) then
3841
ypos := rcToken.Bottom - 1;
3842
cl := DividerInfo.Color;
3843
if cl = clDefault then
3844
cl := fRightEdgeColor;
3845
fTextDrawer.DrawLine(nRightEdge, ypos, TextLeftPixelOffset(False) - 1, ypos, cl);
3846
dec(rcToken.Bottom);
3848
// Initialize highlighter with line text and range info. It is
3849
// necessary because we probably did not scan to the end of the last
3850
// line - the internal highlighter range might be wrong.
3851
fHighlighter.StartAtLineIndex(CurTextIndex);
3852
// Try to concatenate as many tokens as possible to minimize the count
3853
// of ExtTextOut calls necessary. This depends on the selection state
3854
// or the line having special colors. For spaces the foreground color
3855
// is ignored as well.
3856
//debugln('>>>> PaintLines Line=',dbgs(CurLine),' rect=',dbgs(rcToken));
3857
while not fHighlighter.GetEol do begin
3858
fHighlighter.GetTokenEx(sToken,nTokenLen);
3859
attr := fHighlighter.GetTokenAttribute;
3860
// Add Markup to the token and append it to the TokenAccu
3861
// record. This will paint any chars already stored if there is
3862
// a (visible) change in the attributes.
3863
DrawHiLightMarkupToken(attr,sToken,nTokenLen);
3864
// Let the highlighter scan the next token.
3868
// Draw anything that's left in the TokenAccu record. Fill to the end
3869
// of the invalid area with the correct colors.
3870
PaintHighlightToken(TRUE);
3872
fMarkupManager.FinishMarkupForRow(CurTextIndex+1);
3877
{ end local procedures }
3880
if (AClip.Right < TextLeftPixelOffset(False)) then exit;
3881
if (AClip.Left > ClientWidth - TextRightPixelOffset) then exit;
3883
//DebugLn(['TCustomSynEdit.PaintTextLines ',dbgs(AClip)]);
3885
FillChar(TokenAccu,SizeOf(TokenAccu),0);
3886
//DebugLn('TCustomSynEdit.PaintTextLines ',DbgSName(Self),' TopLine=',dbgs(TopLine),' AClip=',dbgs(AClip));
3887
colEditorBG := Color;
3888
if Assigned(fHighlighter) then
3889
fHighlighter.CurrentLines := FTheLinesView;
3890
// If the right edge is visible and in the invalid area, prepare to paint it.
3891
// Do this first to realize the pen when getting the dc variable.
3892
bDoRightEdge := FALSE;
3893
if (fRightEdge > 0) then begin // column value
3894
nRightEdge := fTextOffset + fRightEdge * fCharWidth; // pixel value
3895
if (nRightEdge >= AClip.Left) and (nRightEdge <= AClip.Right) then
3896
bDoRightEdge := TRUE;
3897
if nRightEdge > AClip.Right then
3898
nRightEdge := AClip.Right; // for divider draw lines (don't draw into right gutter)
3901
nRightEdge := AClip.Right;
3903
Canvas.Pen.Color := fRightEdgeColor; // used for code folding too
3904
Canvas.Pen.Width := 1;
3905
// Do everything else with API calls. This (maybe) realizes the new pen color.
3906
dc := Canvas.Handle;
3907
SetBkMode(dc, TRANSPARENT);
3909
// Adjust the invalid area to not include the gutter (nor the 2 ixel offset to the guttter).
3910
EraseLeft := AClip.Left;
3911
if (AClip.Left < TextLeftPixelOffset) then
3912
AClip.Left := TextLeftPixelOffset;
3913
DrawLeft := AClip.Left;
3915
if (LastLine >= FirstLine) then begin
3916
// Paint the visible text lines. To make this easier, compute first the
3917
// necessary information about the selected area: is there any visible
3918
// selected area, and what are its lines / columns?
3919
// Moved to two local procedures to make it easier to read.
3920
fTextDrawer.Style := Font.Style;
3921
fTextDrawer.BeginDrawing(dc);
3925
fTextDrawer.EndDrawing;
3929
AClip.Top := (LastLine+1) * fTextHeight;
3930
if (AClip.Top < AClip.Bottom) then begin
3931
// Delete the remaining area
3932
SetBkColor(dc, ColorToRGB(colEditorBG));
3933
AClip.Left := EraseLeft;
3934
InternalFillRect(dc, AClip);
3935
AClip.Left := DrawLeft;
3937
// Draw the right edge if necessary.
3938
if bDoRightEdge and (not (eoHideRightMargin in Options)) then begin
3939
LCLIntf.MoveToEx(dc, nRightEdge, AClip.Top, nil);
3940
LCLIntf.LineTo(dc, nRightEdge, AClip.Bottom + 1);
3944
fMarkupManager.EndMarkup;
3945
ReAllocMem(TokenAccu.p,0);
3948
3551
procedure TCustomSynEdit.StartPaintBuffer(const ClipRect: TRect);
3949
3552
{$IFDEF EnableDoubleBuf}
6086
5899
FKeystrokes.ResetDefaults;
5902
procedure TCustomSynEdit.ResetMouseActions;
5904
FMouseActions.Options := FMouseOptions;
5905
FMouseActions.ResetUserActions;
5906
FMouseSelActions.Options := FMouseOptions;
5907
FMouseSelActions.ResetUserActions;
5908
FMouseTextActions.Options := FMouseOptions;
5909
FMouseTextActions.ResetUserActions;
5911
FLeftGutter.ResetMouseActions;
5912
FRightGutter.ResetMouseActions;
6089
5915
procedure TCustomSynEdit.CommandProcessor(Command: TSynEditorCommand;
6090
5916
AChar: TUTF8Char;
6091
5917
Data: pointer);
6093
5919
InitialCmd: TSynEditorCommand;
6095
{$IFDEF VerboseKeys}
6096
DebugLn(['[TCustomSynEdit.CommandProcessor] ',Command
6097
,' AChar=',AChar,' Data=',DbgS(Data)]);
6099
// first the program event handler gets a chance to process the command
6100
InitialCmd := Command;
6101
DoOnProcessCommand(Command, AChar, Data);
6102
if Command <> ecNone then begin
6104
InternalBeginUndoBlock;
6105
FBeautifyStartLineIdx := -1;
6106
FBeautifyEndLineIdx := -1;
6107
if assigned(FBeautifier) then begin
6108
FBeautifier.AutoIndent := (eoAutoIndent in FOptions);
6109
FBeautifier.BeforeCommand(self, FTheLinesView, FCaret, Command, InitialCmd);
6111
// notify hooked command handlers before the command is executed inside of
6113
if Command <> ecNone then
6114
NotifyHookedCommandHandlers(FALSE, Command, AChar, Data);
6115
// internal command handler
6116
if (Command <> ecNone) and (Command < ecUserFirst) then
6117
ExecuteCommand(Command, AChar, Data);
6118
// notify hooked command handlers after the command was executed inside of
6120
if Command <> ecNone then
6121
NotifyHookedCommandHandlers(TRUE, Command, AChar, Data);
6122
if Command <> ecNone then
6123
DoOnCommandProcessed(Command, AChar, Data);
5923
{$IFDEF VerboseKeys}
5924
DebugLn(['[TCustomSynEdit.CommandProcessor] ',Command
5925
,' AChar=',AChar,' Data=',DbgS(Data)]);
5927
// first the program event handler gets a chance to process the command
5928
InitialCmd := Command;
5929
NotifyHookedCommandHandlers(Command, AChar, Data, hcfInit);
5930
DoOnProcessCommand(Command, AChar, Data);
5931
if Command <> ecNone then begin
5933
InternalBeginUndoBlock;
5934
FBeautifyStartLineIdx := -1;
5935
FBeautifyEndLineIdx := -1;
5936
if assigned(FBeautifier) then begin
5937
FBeautifier.AutoIndent := (eoAutoIndent in FOptions);
5938
FBeautifier.BeforeCommand(self, FTheLinesView, FCaret, Command, InitialCmd);
5940
// notify hooked command handlers before the command is executed inside of
5942
if Command <> ecNone then
5943
NotifyHookedCommandHandlers(Command, AChar, Data, hcfPreExec);
5944
// internal command handler
5945
if (Command <> ecNone) and (Command < ecUserFirst) then
5946
ExecuteCommand(Command, AChar, Data);
5947
// notify hooked command handlers after the command was executed inside of
5949
if Command <> ecNone then
5950
NotifyHookedCommandHandlers(Command, AChar, Data, hcfPostExec);
5951
if Command <> ecNone then
5952
DoOnCommandProcessed(Command, AChar, Data);
6125
if assigned(FBeautifier) then begin
6126
tsyneditstringlist(FLines).FlushNotificationCache;
6127
FBeautifier.AutoIndent := (eoAutoIndent in FOptions);
6128
FBeautifier.AfterCommand(self, FTheLinesView, FCaret, Command, InitialCmd,
6129
FBeautifyStartLineIdx+1, FBeautifyEndLineIdx+1);
5954
if assigned(FBeautifier) then begin
5955
tsyneditstringlist(FLines).FlushNotificationCache;
5956
FBeautifier.AutoIndent := (eoAutoIndent in FOptions);
5957
FBeautifier.AfterCommand(self, FTheLinesView, FCaret, Command, InitialCmd,
5958
FBeautifyStartLineIdx+1, FBeautifyEndLineIdx+1);
5961
InternalEndUndoBlock;
5962
{$IFDEF SynCheckPaintLock}
5963
if (FPaintLock > 0) and (FInvalidateRect.Bottom > FInvalidateRect.Top) then begin
5964
debugln(['TCustomSynEdit.CommandProcessor: Paint called while locked InitialCmd=', InitialCmd, ' Command=', Command]);
6132
InternalEndUndoBlock;
5970
NotifyHookedCommandHandlers(Command, AChar, Data, hcfFinish);
6137
5976
procedure TCustomSynEdit.ExecuteCommand(Command: TSynEditorCommand;
6138
5977
const AChar: TUTF8Char; Data: pointer);
6140
ALPHANUMERIC = DIGIT + ALPHA_UC + ALPHA_LC;
6141
5979
SEL_MODE: array[ecNormalSelect..ecLineSelect] of TSynSelectionMode = (
6142
5980
smNormal, smColumn, smLine);