1 {
2 Copyright (C) Alexey Torgashin, uvviewsoft.com
3 License: MPL 2.0 or LGPL
4 }
5 
6 {$mode objfpc}{$H+}
7 {$ModeSwitch advancedrecords}
8 
9 {$I atsynedit_defines.inc}
10 
11 unit ATSynEdit;
12 
13 interface
14 
15 uses
16   {$ifdef Windows}
17   Windows, Messages,
18   ATSynEdit_Adapter_IME,
19   {$endif}
20   InterfaceBase,
21   Classes, SysUtils, Graphics,
22   Controls, ExtCtrls, Menus, Forms, Clipbrd,
23   syncobjs, gdeque,
24   LMessages, LCLType, LCLVersion,
25   LazUTF8,
26   EncConv,
27   BGRABitmap,
28   BGRABitmapTypes,
29   ATStringProc,
30   ATStringProc_Separator,
31   ATStrings,
32   ATStringProc_WordJump,
33   ATCanvasPrimitives,
34   ATSynEdit_Options,
35   ATSynEdit_CharSizer,
36   {$ifdef USE_FPC_REGEXPR}
37   RegExpr,
38   {$else}
39   ATSynEdit_RegExpr,
40   {$endif}
41   ATSynEdit_Colors,
42   ATSynEdit_Keymap,
43   ATSynEdit_LineParts,
44   ATSynEdit_CanvasProc,
45   ATSynEdit_Carets,
46   ATSynEdit_Markers,
47   ATSynEdit_Gutter,
48   ATSynEdit_Gutter_Decor,
49   ATSynEdit_WrapInfo,
50   ATSynEdit_Bookmarks,
51   ATSynEdit_Ranges,
52   ATSynEdit_DimRanges,
53   ATSynEdit_Gaps,
54   ATSynEdit_Hotspots,
55   ATSynEdit_Micromap,
56   ATSynEdit_Adapters,
57   ATSynEdit_Adapter_Cache,
58   ATSynEdit_LinkCache,
59   ATSynEdit_FGL,
60   ATScrollBar;
61 
62 {$ifdef LCLGTK2}
63   {$if (LCL_FULLVERSION >= 2030000)}
64     {$define GTK2_IME_CODE}
65   {$endif}
66 {$endif}
67 
68 type
69   TATPoint64 = record
70     X, Y: Int64
71   end;
72 
73   TATRect64 = record
74     Left, Top, Right, Bottom: Int64;
75   end;
76 
77 type
78   TATEditorCommandInvoke = (
79     cInvokeInternal,
80     cInvokeHotkey,
81     cInvokeHotkeyChar,
82     cInvokeMenuContext,
83     cInvokeMenuMain,
84     cInvokeMenuAPI,
85     cInvokeAppInternal,
86     cInvokeAppPalette,
87     cInvokeAppToolbar,
88     cInvokeAppSidebar,
89     cInvokeAppCharMap,
90     cInvokeAppDragDrop,
91     cInvokeAppAPI
92     );
93 
94 const
95   cEditorCommandInvoke: array[TATEditorCommandInvoke] of string = (
96     'int',
97     'key',
98     'key_char',
99     'menu_ctx',
100     'menu_main',
101     'menu_api',
102     'app_int',
103     'app_pal',
104     'app_toolbar',
105     'app_sidebar',
106     'app_charmap',
107     'app_dragdrop',
108     'app_api'
109     );
110 
111 type
112   TATEditorCommandLogItem = record
113   public
114     ItemInvoke: TATEditorCommandInvoke;
115     ItemCode: integer;
116     //don't use 'string' here! it gives crashes on freeing of editor objects
117     ItemText: string[220];
118   end;
119 
120   { TATEditorCommandLog }
121 
122   TATEditorCommandLog = class(specialize TDeque<TATEditorCommandLogItem>)
123   public
124     MaxCount: integer;
125     constructor Create;
126     procedure Add(ACode: integer; AInvoke: TATEditorCommandInvoke; const AText: string);
127   end;
128 
129   TATEditorWheelRecord = record
130     Kind: (wqkVert, wqkHorz, wqkZoom);
131     Delta: integer;
132   end;
133 
134   //TATEditorWheelQueue = specialize TQueue<TATEditorWheelRecord>;
135 
136 type
137   TATTokenKind = (
138     atkOther,
139     atkComment,
140     atkString
141     );
142 
143   TATEditorScrollbarStyle = (
144     aessHide,
145     aessShow,
146     aessAuto
147     );
148 
149   TATEditorMiddleClickAction = (
150     mcaNone,
151     mcaScrolling,
152     mcaPaste,
153     mcaGotoDefinition
154     );
155 
156   TATEditorPosDetails = record
157     EndOfWrappedLine: boolean;
158     OnGapItem: TATGapItem;
159     OnGapPos: TPoint;
160   end;
161 
162   TATEditorDoubleClickAction = (
163     cMouseDblClickNone,
164     cMouseDblClickSelectWordChars,
165     cMouseDblClickSelectAnyChars,
166     cMouseDblClickSelectEntireLine
167     );
168 
169   TATEditorMouseAction = (
170     cMouseActionNone,
171     cMouseActionClickSimple,
172     cMouseActionClickRight,
173     cMouseActionClickAndSelNormalBlock,
174     cMouseActionClickAndSelVerticalBlock,
175     cMouseActionClickMiddle,
176     cMouseActionMakeCaret,
177     cMouseActionMakeCaretsColumn
178     );
179 
180   TATEditorMouseActionRecord = record
181     MouseState: TShiftState;
182     MouseActionId: TATEditorMouseAction;
183   end;
184 
185   TATEditorMouseActionArray = array of TATEditorMouseActionRecord;
186 
187   TATFoldBarState = (
188     cFoldbarNone,
189     cFoldbarBegin,
190     cFoldbarEnd,
191     cFoldbarMiddle
192     );
193 
194   TATFoldBarProps = record
195     State: TATFoldBarState;
196     IsPlus: boolean;
197     IsLineUp: boolean;
198     IsLineDown: boolean;
199     HiliteLines: boolean;
200   end;
201 
202   TATFoldBarPropsArray = array of TATFoldBarProps;
203 
204   TATEditorDirection = (
205     cDirNone,
206     cDirLeft,
207     cDirRight,
208     cDirUp,
209     cDirDown
210     );
211 
212   TATEditorRulerNumeration = (
213     cRulerNumeration_0_10_20,
214     cRulerNumeration_1_11_21,
215     cRulerNumeration_1_10_20
216     );
217 
218   TATEditorSelectColumnDirection = (
219     cDirColumnLeft,
220     cDirColumnRight,
221     cDirColumnUp,
222     cDirColumnDown,
223     cDirColumnPageUp,
224     cDirColumnPageDown
225     );
226 
227   TATEditorScrollbarsArrowsKind = (
228     cScrollArrowsNormal,
229     cScrollArrowsHidden,
230     cScrollArrowsAbove,
231     cScrollArrowsBelow,
232     cScrollArrowsCorner
233     );
234 
235   TATEditorCaseConvert = (
236     cCaseLower,
237     cCaseUpper,
238     cCaseTitle,
239     cCaseInvert,
240     cCaseSentence
241     );
242 
243   TATCommandResult = (
244     cResultText,             //Text was changed.
245     cResultFoldChange,       //Folding range(s) were changed or folded/unfolded.
246     cResultCaretAny,         //Caret(s) pos/selection was changed. Don't scroll to caret.
247     cResultCaretLeft,        //Caret(s) pos/selection was changed. Scroll to the most left caret.
248     cResultCaretTop,         //Caret(s) pos/selection was changed. Scroll to the first caret.
249     cResultCaretRight,       //Caret(s) pos/selection was changed. Scroll to the most right caret.
250     cResultCaretBottom,      //Caret(s) pos/selection was changed. Scroll to the last caret.
251     cResultCaretLazy,  //Additional to CaretLeft/CaretRight/CaretTop/CaretBottom, scrolls only if no carets are left in visible area.
252     cResultCaretFarFromEdge, //Before running the command, caret was far from both vertical edges
253     cResultKeepColumnSel,    //Restore previous column selection, if command changed it.
254     cResultScroll,           //Some scrolling was made.
255     cResultUndoRedo,         //Undo or Redo action was made.
256     cResultState             //Some properties of editor were changed (e.g. word-wrap state).
257     );
258   TATCommandResults = set of TATCommandResult;
259 
260   TATEditorGapCoordAction = (
261     cGapCoordIgnore,
262     cGapCoordToLineEnd,
263     cGapCoordMoveDown
264     );
265 
266   TATEditorGutterIcons = (
267     cGutterIconsPlusMinus,
268     cGutterIconsTriangles
269     );
270 
271   TATEditorPasteCaret = (
272     cPasteCaretNoChange,
273     cPasteCaretLeftBottom,
274     cPasteCaretRightBottom,
275     cPasteCaretRightTop,
276     cPasteCaretColumnLeft,
277     cPasteCaretColumnRight
278     );
279 
280   TATEditorFoldStyle = ( //affects folding of blocks without "text hint" passed from adapter
281     cFoldHereWithDots, //show "..." from fold-pos
282     cFoldHereWithTruncatedText, //show truncated line instead of "..."
283     cFoldFromEndOfLine, //looks like Lazarus: show "..." after line, bad with 2 blocks starting at the same line
284     cFoldFromEndOfLineAlways, //same, even if HintText not empty
285     cFoldFromNextLine //looks like SynWrite: don't show "...", show separator line
286     );
287 
288   TATEditorFoldRangeCommand = (
289     cFoldingFold,
290     cFoldingUnfold,
291     cFoldingToggle
292     );
293 
294   TATEditorStapleEdge = (
295     cStapleEdgeNone,
296     cStapleEdgeAngle,
297     cStapleEdgeLine
298     );
299 
300 type
301   TATEditorAutoIndentKind = (
302     cIndentAsPrevLine,
303     cIndentSpacesOnly,
304     cIndentTabsAndSpaces,
305     cIndentTabsOnly,
306     cIndentToOpeningBracket
307     );
308 
309   TATEditorPageDownSize = (
310     cPageSizeFull,
311     cPageSizeFullMinus1,
312     cPageSizeHalf
313     );
314 
315   TATEditorWrapMode = (
316     cWrapOff,
317     cWrapOn,
318     cWrapAtMargin,
319     cWrapAtWindowOrMargin
320     );
321 
322   TATEditorNumbersStyle = (
323     cNumbersAll,
324     cNumbersNone,
325     cNumbersEach10th,
326     cNumbersEach5th,
327     cNumbersRelative
328     );
329 
330   TATEditorInternalFlag = (
331     cIntFlagBitmap,
332     cIntFlagScrolled,
333     cIntFlagResize
334     );
335   TATEditorInternalFlags = set of TATEditorInternalFlag;
336 
337   { TATEditorScrollInfo }
338 
339   TATEditorScrollInfo = record
340   private
341     procedure SetNPos(const AValue: Int64);
342   public
343     Vertical: boolean;
344     NMax: Int64;
345     NPage: Int64;
346     NPos_: Int64;
347     NPosLast: Int64;
348     NPixelOffset: Int64;
349     SmoothCharSize: Int64;
350     SmoothMax: Int64;
351     SmoothPage: Int64;
352     SmoothPos: Int64;
353     SmoothPosLast: Int64;
354     property NPos: Int64 read NPos_ write SetNPos; //only for debugging
355     procedure Clear;
356     procedure SetZero; inline;
357     procedure SetLast; inline;
358     function TopGapVisible: boolean; inline;
359     function TotalOffset: Int64; inline;
360     class operator =(const A, B: TATEditorScrollInfo): boolean;
361   end;
362 
363 type
364   { TATCaretShape }
365 
366   TATCaretShape = class
367   public
368     //Value>=0: in pixels
369     //Value<0: in percents
370     //Value<-100: caret is bigger than cell and overlaps nearest cells
371     Width: integer;
372     Height: integer;
373     EmptyInside: boolean;
374     procedure Assign(Obj: TATCaretShape);
375   end;
376 
377 type
378   { TMinimapThread }
379 
380   TATMinimapThread = class(TThread)
381   public
382     Editor: TObject;
383   protected
384     procedure Execute; override;
385   end;
386 
387 const
388   cUsePaintStatic = true;
389   cMaxIndentVert = 100;
390   cInitTextOffsetLeft = 0;
391   cInitTextOffsetTop = 2;
392   cInitHighlightGitConflicts = true;
393   cInitAutoPairForMultiCarets = true;
394   cInitInputNumberAllowNegative = true;
395   cInitMaskChar = '*';
396   cInitScrollAnimationSteps = 4;
397   cInitScrollAnimationSleep = 0;
398   cInitUndoLimit = 5000;
399   cInitUndoMaxCarets = 20000;
400   cInitUndoIndentVert = 15;
401   cInitUndoIndentHorz = 20;
402   cInitUndoPause = 300;
403   cInitUndoPause2 = 1000;
404   cInitUndoPauseHighlightLine = true;
405   cInitUndoForCaretJump = true;
406   cInitMicromapShowForMinCount = 2;
407   cInitScrollbarHorzAddSpace = 2;
408   cInitIdleInterval = 0; //1000; //0 dont fire OnIdle, faster
409   cInitCaretsPrimitiveColumnSelection = true;
410   cInitCaretsMultiToColumnSel = true;
411   cInitBorderVisible = true;
412   cInitBorderWidth = 1;
413   cInitBorderWidthFocused = 1;
414   cInitBorderWidthMacro = 3;
415   cInitRulerNumeration = cRulerNumeration_0_10_20;
416   cInitWrapMode = cWrapOff;
417   cInitWrapEnabledForMaxLines = 60*1000;
418   cInitSpacingY = 1;
419   cInitCaretBlinkTime = 600;
420   cInitTimerAutoScroll = 100;
421   cInitTimerNiceScroll = 100;
422   cInitMinimapVisible = false;
423   cInitMinimapSelColorChange = 6; //how much minimap sel-rect is darker, in %
424   cInitMinimapTooltipVisible = true;
425   cInitMinimapTooltipLinesCount = 6;
426   cInitMinimapTooltipWidthPercents = 60;
427   cInitMicromapVisible = false;
428   cInitMicromapOnScrollbar = false;
429   cInitMicromapBookmarks = false;
430   cInitShowMouseSelFrame = true;
431   cInitMarginRight = 80;
432   cInitTabSize = 8;
433   cInitNumbersStyle = cNumbersEach5th;
434   cInitNumbersIndentPercents = 60;
435   cInitBitmapWidth = 1000;
436   cInitBitmapHeight = 800;
437   cInitGutterPlusSize = 4;
438   cInitMarkerSize = 30;
439   cInitFoldStyle = cFoldHereWithTruncatedText;
440   cInitFoldUnderlineOffset = 3;
441   cInitFoldTooltipVisible = true;
442   cInitFoldTooltipLineCount = 15;
443   cInitFoldTooltipWidthPercents = 80;
444   cInitMaxLineLenToTokenize = 4000;
445   cInitMinLineLenToCalcURL = 4;
446   cInitMaxLineLenToCalcURL = 300;
447   cInitDragDropMarkerWidth = 4;
448   cInitStapleHiliteAlpha = 180;
449   cInitZebraAlphaBlend = 235;
450   cInitDimUnfocusedBack = 0;
451   cInitShowFoldedMarkWithSelectionBG = true;
452 
453   cGutterBands = 6;
454   cGutterSizeBm = 16;
455   cGutterSizeNum = 10;
456   cGutterSizeFold = 14;
457   cGutterSizeState = 3;
458   cGutterSizeSep = 1;
459   cGutterSizeEmpty = 2;
460 
461 const
462   cFoldedLenOfEmptyHint = 50;
463   cFoldedMarkIndentInner = 2; //indent inside [...] folded-mark
464   cFoldedMarkIndentOuter = 2; //indent before [...] folded-mark
465   cSpeedScrollNice: integer = 3;
466   cSizeGutterFoldLineDx = 3;
467   cSizeRulerHeightPercents = 120;
468   cSizeRulerMarkSmall = 3;
469   cSizeRulerMarkBig = 7;
470   cSizeRulerMarkCaret = 1;
471   cSizeIndentTooltipX = 5;
472   cSizeIndentTooltipY = 1;
473   cMinFontSize = 6;
474   cMinTabSize = 1;
475   cMaxTabSize = 64;
476   cMinMinimapWidth = 30;
477   cMaxCharsForOutput = 1000; //don't paint more chars in line
478   cMinWrapColumn = 20; //too small width won't give smaller wrap-column
479   cMinWrapColumnAbs = 4; //absolute min of wrap-column (leave n chars on line anyway)
480   cMinMarginRt = 20;
481   cMinCaretTime = 300;
482   cMaxCaretTime = 2000;
483   cMinCharsAfterAnyIndent = 20; //if indent is too big, leave 20 chrs in wrapped-parts anyway
484   cMaxLinesForOldWrapUpdate = 100; //if less lines, force old wrapinfo update (fast)
485   cHintScrollDx = 5;
486   cHintBookmarkDx = 6;
487   cHintBookmarkDy = 16;
488   cUrlMarkerTag = -100;
489 
490   cUrlRegex_Email = '\b(mailto:)?\w[\w\-\+\.]*@\w[\w\-\.]*\.\w{2,}\b';
491   cUrlRegex_WebBegin = 'https?://|ftp://|magnet:\?|www\.|ftp\.';
492   cUrlRegex_WebSite = '\w[\w\-\.@]*(:\d+)?'; // @ for password; :\d+ is port
493   cUrlRegex_WebAnchor = '(\#[\w\-/]*)?';
494   cUrlRegex_WebParams = '(\?[^<>''"\s]+)?';
495   cUrlRegex_Web =
496     '\b(' + cUrlRegex_WebBegin + ')'
497     + cUrlRegex_WebSite
498     + '(/[~\w\.\-\+\/%@]*)?' //folders
499     + cUrlRegex_WebParams
500     + cUrlRegex_WebAnchor;
501   cUrlRegexInitial = cUrlRegex_Email + '|' + cUrlRegex_Web;
502 
503   cTextHintScrollPrefix: string = 'Line';
504 
505   cStrMenuitemFoldAll: string = 'Fold all';
506   cStrMenuitemUnfoldAll: string = 'Unfold all';
507   cStrMenuitemFoldLevel: string = 'Fold level';
508   cStrMenuitemCut: string = 'Cut';
509   cStrMenuitemCopy: string = 'Copy';
510   cStrMenuitemPaste: string = 'Paste';
511   cStrMenuitemDelete: string = 'Delete';
512   cStrMenuitemSelectAll: string = 'Select all';
513   cStrMenuitemUndo: string = 'Undo';
514   cStrMenuitemRedo: string = 'Redo';
515 
516 var
517   cRectEmpty: TRect = (Left: 0; Top: 0; Right: 0; Bottom: 0);
518   ATClipboardColumnFormat: TClipboardFormat = 0; //must be inited
519   ATClipboardColumnSignature: integer = $1000;
520 
521 type
522   TATSynEditClickEvent = procedure(Sender: TObject; var AHandled: boolean) of object;
523   TATSynEditClickMoveCaretEvent = procedure(Sender: TObject; APrevPnt, ANewPnt: TPoint) of object;
524   TATSynEditClickGapEvent = procedure(Sender: TObject; AGapItem: TATGapItem; APos: TPoint) of object;
525   TATSynEditCommandEvent = procedure(Sender: TObject; ACommand: integer; AInvoke: TATEditorCommandInvoke; const AText: string; var AHandled: boolean) of object;
526   TATSynEditCommandAfterEvent = procedure(Sender: TObject; ACommand: integer; const AText: string) of object;
527   TATSynEditClickGutterEvent = procedure(Sender: TObject; ABand: integer; ALineNum: integer) of object;
528   TATSynEditClickMicromapEvent = procedure(Sender: TObject; AX, AY: integer) of object;
529   TATSynEditClickLinkEvent = procedure(Sender: TObject; const ALink: string) of object;
530   TATSynEditDrawBookmarkEvent = procedure(Sender: TObject; C: TCanvas; ALineNum: integer; const ARect: TRect) of object;
531   TATSynEditDrawRectEvent = procedure(Sender: TObject; C: TCanvas; const ARect: TRect) of object;
532   TATSynEditDrawGapEvent = procedure(Sender: TObject; C: TCanvas; const ARect: TRect; AGap: TATGapItem) of object;
533   TATSynEditCalcBookmarkColorEvent = procedure(Sender: TObject; ABookmarkKind: integer; var AColor: TColor) of object;
534   TATSynEditCalcStapleEvent = procedure(Sender: TObject; ALine, AIndent: integer; var AStapleColor: TColor) of object;
535   TATSynEditCalcHiliteEvent = procedure(Sender: TObject; var AParts: TATLineParts;
536     ALineIndex, ACharIndex, ALineLen: integer; var AColorAfterEol: TColor) of object;
537   TATSynEditPasteEvent = procedure(Sender: TObject; var AHandled: boolean;
538     AKeepCaret, ASelectThen: boolean) of object;
539   TATSynEditHotspotEvent = procedure(Sender: TObject; AHotspotIndex: integer) of object;
540   TATSynEditCheckInputEvent = procedure(Sender: TObject; AChar: WideChar; var AllowInput: boolean) of object;
541 
542 type
543   { TATFoldedMark }
544 
545   TATFoldedMark = record
546   public
547     Coord: TRect;
548     LineFrom, LineTo: integer;
549     procedure Init(const ACoord: TRect; ALineFrom, ALineTo: integer);
550     procedure InitNone;
551     function IsInited: boolean;
552     class operator =(const a, b: TATFoldedMark): boolean;
553   end;
554 
555   { TATFoldedMarks }
556 
557   TATFoldedMarks = class(specialize TFPGList<TATFoldedMark>)
558   public
559     function FindByCoord(ACoord: TPoint): TATFoldedMark;
560   end;
561 
562   TATEditorTempOptions = record
563     FontSize: integer;
564     WrapMode: TATEditorWrapMode;
565     ShowMinimap: boolean;
566     ShowMicromap: boolean;
567     ShowRuler: boolean;
568     ShowNumbers: boolean;
569     ShowFolding: boolean;
570     ShowUnprinted: boolean;
571     UnprintedSpaces: boolean;
572     UnprintedSpacesTrail: boolean;
573     UnprintedSpacesInSel: boolean;
574     UnprintedEnds: boolean;
575     UnprintedEndsDetails: boolean;
576   end;
577 
578 type
579   { TATSynEdit }
580 
581   TATSynEdit = class(TCustomControl)
582   private
583     FFontItalic: TFont;
584     FFontBold: TFont;
585     FFontBoldItalic: TFont;
586     FTimersEnabled: boolean;
587     FTimerIdle: TTimer;
588     FTimerBlink: TTimer;
589     FTimerScroll: TTimer;
590     FTimerNiceScroll: TTimer;
591     FTimerDelayedParsing: TTimer;
592     FTimerFlicker: TTimer;
593     FPaintFlags: TATEditorInternalFlags;
594     FPaintLocked: integer;
595     FBitmap: TBitmap;
596     FKeymap: TATKeymap;
597     FKeymapHistory: TATKeyArray;
598     //FBrotherEditor: TATSynEdit;
599     FCudatextFrame: TCustomFrame;
600     FWantTabs: boolean;
601     FWantReturns: boolean;
602     FEditorIndex: integer;
603     FMarginRight: integer;
604     FMarginList: array of integer;
605     FStringsInt: TATStrings;
606     FStringsExternal: TATStrings;
607     FTabHelper: TATStringTabHelper;
608     FAdapterHilite: TATAdapterHilite;
609     FAdapterIME: TATAdapterIME;
610     FFold: TATSynRanges;
611     FFoldImageList: TImageList;
612     FFoldStyle: TATEditorFoldStyle;
613     FFoldUnderlineOffset: integer;
614     FFoldEnabled: boolean;
615     FFoldCacheEnabled: boolean;
616     FFoldTooltipVisible: boolean;
617     FFoldTooltipWidthPercents: integer;
618     FFoldTooltipLineCount: integer;
619     FCursorText: TCursor;
620     FCursorColumnSel: TCursor;
621     FCursorGutterBookmark: TCursor;
622     FCursorGutterNumbers: TCursor;
623     FCursorMinimap: TCursor;
624     FCursorMicromap: TCursor;
625     FTextOffset: TPoint;
626     FTextOffsetFromTop: integer;
627     FTextOffsetFromTop1: integer;
628     FTextHint: string;
629     FTextHintFontStyle: TFontStyles;
630     FTextHintCenter: boolean;
631     FSel: TATCaretSelections;
632     FSelRect: TRect;
633     FSelRectBegin: TPoint;
634     FSelRectEnd: TPoint;
635     FVisibleColumns: integer;
636     FCommandLog: TATEditorCommandLog;
637     FCarets: TATCarets;
638     FCaretShowEnabled: boolean;
639     FCaretShown: boolean;
640     FCaretBlinkEnabled: boolean;
641     FCaretBlinkTime: integer;
642     FCaretShapeNormal: TATCaretShape;
643     FCaretShapeOverwrite: TATCaretShape;
644     FCaretShapeReadonly: TATCaretShape;
645     FCaretVirtual: boolean;
646     FCaretSpecPos: boolean;
647     FCaretStopUnfocused: boolean;
648     FCaretHideUnfocused: boolean;
649     FCaretAllowNextBlink: boolean;
650     FIsEntered: boolean;
651     FMarkers: TATMarkers;
652     FAttribs: TATMarkers;
653     FMarkedRange: TATMarkers;
654     FDimRanges: TATDimRanges;
655     FHotspots: TATHotspots;
656     FRegexLinks: TRegExpr;
657     FLinkCache: TATLinkCache;
658     FFileName: string;
659     FMenuStd: TPopupMenu;
660     FMenuText: TPopupMenu;
661     FMenuGutterBm: TPopupMenu;
662     FMenuGutterNum: TPopupMenu;
663     FMenuGutterFold: TPopupMenu;
664     FMenuGutterFoldStd: TPopupMenu;
665     FMenuMinimap: TPopupMenu;
666     FMenuMicromap: TPopupMenu;
667     FMenuRuler: TPopupMenu;
668     MenuitemTextCut: TMenuItem;
669     MenuitemTextCopy: TMenuItem;
670     MenuitemTextPaste: TMenuItem;
671     MenuitemTextDelete: TMenuItem;
672     MenuitemTextSelAll: TMenuItem;
673     MenuitemTextUndo: TMenuItem;
674     MenuitemTextRedo: TMenuItem;
675     FOverwrite: boolean;
676     FHintWnd: THintWindow;
677     FMouseDownCoordOriginal: TPoint;
678     FMouseDownCoord: TPoint;
679     FMouseDragCoord: TPoint;
680     FMouseDownPnt: TPoint;
681     FMouseDownGutterLineNumber: integer;
682     FMouseDownOnMinimap: boolean;
683     FMouseDownDouble: boolean;
684     FMouseDownWithCtrl: boolean;
685     FMouseDownWithAlt: boolean;
686     FMouseDownWithShift: boolean;
687     FMouseNiceScrollPos: TPoint;
688     FMouseDragDropping: boolean;
689     FMouseDragDroppingReal: boolean;
690     FMouseDragMinimap: boolean;
691     FMouseDragMinimapDelta: integer;
692     FMouseDragMinimapSelHeight: integer;
693     FMouseDownAndColumnSelection: boolean;
694     FMouseAutoScroll: TATEditorDirection;
695     FMouseActions: TATEditorMouseActionArray;
696     FLockInput: boolean;
697     FLastControlWidth: integer;
698     FLastControlHeight: integer;
699     FLastHotspot: integer;
700     FLastTextCmd: integer;
701     FLastTextCmdText: atString;
702     FLastCommand: integer;
703     FLastCommandChangedText: boolean;
704     FLastCommandChangedText2: boolean;
705     FLastCommandMakesColumnSel: boolean;
706     FLastCommandDelayedParsingOnLine: integer;
707     FLastLineOfSlowEvents: integer;
708     FLastUndoTick: QWord;
709     FLastUndoPaused: boolean;
710     FLineTopTodo: integer;
711     FIsCaretShapeChangedFromAPI: boolean;
712     FIsReadOnlyChanged: boolean;
713     FIsReadOnlyAutodetected: boolean;
714     FIsMacroRecording: boolean;
715     FIsRunningCommand: boolean;
716     FCursorOnMinimap: boolean;
717     FCursorOnGutter: boolean;
718     FFoldbarCache: TATFoldBarPropsArray;
719     FFoldbarCacheStart: integer;
720     FAdapterIsDataReady: boolean;
721     FOnCheckInput: TATSynEditCheckInputEvent;
722     FOnBeforeCalcHilite: TNotifyEvent;
723     FOnClickDbl,
724     FOnClickTriple,
725     FOnClickMiddle: TATSynEditClickEvent;
726     FOnClickMoveCaret: TATSynEditClickMoveCaretEvent;
727     FOnClickGap: TATSynEditClickGapEvent;
728     FOnClickEndSelect: TATSynEditClickMoveCaretEvent;
729     FOnClickLink: TATSynEditClickLinkEvent;
730     FOnIdle: TNotifyEvent;
731     FOnChange: TNotifyEvent;
732     FOnChangeLog: TATStringsChangeLogEvent;
733     FOnChangeCaretPos: TNotifyEvent;
734     FOnChangeState: TNotifyEvent;
735     FOnChangeZoom: TNotifyEvent;
736     FOnChangeModified: TNotifyEvent;
737     FOnChangeBookmarks: TNotifyEvent;
738     FOnScroll: TNotifyEvent;
739     FOnClickGutter: TATSynEditClickGutterEvent;
740     FOnClickMicromap: TATSynEditClickMicromapEvent;
741     FOnDrawBookmarkIcon: TATSynEditDrawBookmarkEvent;
742     FOnDrawGap: TATSynEditDrawGapEvent;
743     FOnDrawLine: TATSynEditDrawLineEvent;
744     FOnDrawMicromap: TATSynEditDrawRectEvent;
745     FOnDrawEditor: TATSynEditDrawRectEvent;
746     FOnDrawRuler: TATSynEditDrawRectEvent;
747     FOnCommand: TATSynEditCommandEvent;
748     FOnCommandAfter: TATSynEditCommandAfterEvent;
749     FOnCalcHilite: TATSynEditCalcHiliteEvent;
750     FOnCalcStaple: TATSynEditCalcStapleEvent;
751     FOnCalcBookmarkColor: TATSynEditCalcBookmarkColorEvent;
752     FOnCalcTabSize: TATStringTabCalcEvent;
753     FOnPaste: TATSynEditPasteEvent;
754     FOnHotspotEnter: TATSynEditHotspotEvent;
755     FOnHotspotExit: TATSynEditHotspotEvent;
756     FWrapInfo: TATWrapInfo;
757     FWrapTemps: TATWrapItems;
758     FWrapMode: TATEditorWrapMode;
759     FWrapUpdateNeeded: boolean;
760     FWrapIndented: boolean;
761     FWrapAddSpace: integer;
762     FWrapEnabledForMaxLines: integer;
763     //FWheelQueue: TATEditorWheelQueue;
764     FUnprintedVisible,
765     FUnprintedSpaces,
766     FUnprintedSpacesTrailing,
767     FUnprintedSpacesBothEnds,
768     FUnprintedSpacesOnlyInSelection,
769     FUnprintedEof,
770     FUnprintedEnds,
771     FUnprintedEndsDetails: boolean;
772     FPrevModified: boolean;
773     FCharSize: TATEditorCharSize;
774     FCharSizeMinimap: TATEditorCharSize;
775     FSpacingY: integer;
776     FTabSize: integer;
777     FGutter: TATGutter;
778     FGutterDecor: TATGutterDecor;
779     FGutterDecorImages: TImageList;
780     FGutterDecorAlignment: TAlignment;
781     FGutterBandBookmarks: integer;
782     FGutterBandNumbers: integer;
783     FGutterBandStates: integer;
784     FGutterBandFolding: integer;
785     FGutterBandSeparator: integer;
786     FGutterBandEmpty: integer;
787     FGutterBandDecor: integer;
788     FColors: TATEditorColors;
789     FColorFont: TColor;
790     FColorBG: TColor;
791     FRulerHeight: integer;
792     FNumbersIndent: integer;
793     FRectMain,
794     FRectMainVisible,
795     FRectMinimap,
796     FRectMicromap,
797     FRectGutter,
798     FRectRuler: TRect;
799     FClientW: integer; //saved on Paint, to avoid calling Controls.ClientWidth/ClientHeight
800     FClientH: integer;
801     FLineBottom: integer;
802     FParts: TATLineParts; //this is used in DoPaintLine
803     FPartsMinimap: TATLineParts; //this is used by DoPaintMinimapLine, in thread
804     FPartsSel: TATLineParts; //this is used in DoPartCalc_ApplySelectionOver
805     FScrollVert,
806     FScrollHorz,
807     FScrollVertMinimap,
808     FScrollHorzMinimap: TATEditorScrollInfo;
809     FScrollbarVert,
810     FScrollbarHorz: TATScrollbar;
811     FScrollbarLock: boolean;
812     FPrevHorz,
813     FPrevVert: TATEditorScrollInfo;
814     FMinimapWidth: integer;
815     FMinimapCharWidth: integer;
816     FMinimapCustomScale: integer;
817     FMinimapVisible: boolean;
818     FMinimapShowSelBorder: boolean;
819     FMinimapShowSelAlways: boolean;
820     FMinimapSelColorChange: integer;
821     FMinimapAtLeft: boolean;
822     FMinimapTooltipVisible: boolean;
823     FMinimapTooltipEnabled: boolean;
824     FMinimapTooltipBitmap: TBitmap;
825     FMinimapTooltipLinesCount: integer;
826     FMinimapTooltipWidthPercents: integer;
827     FMinimapHiliteLinesWithSelection: boolean;
828     FMinimapDragImmediately: boolean;
829     FMicromap: TATMicromap;
830     FMicromapVisible: boolean;
831     FMicromapOnScrollbar: boolean;
832     FMicromapLineStates: boolean;
833     FMicromapSelections: boolean;
834     FMicromapBookmarks: boolean;
835     FMicromapScaleDiv: integer;
836     FMicromapShowForMinCount: integer;
837     FFoldedMarkList: TATFoldedMarks;
838     FFoldedMarkCurrent: TATFoldedMark;
839     FFoldedMarkTooltip: TPanel;
840     FPaintCounter: integer;
841     FPaintStarted: boolean;
842     FPaintWorking: boolean;
843     FTickMinimap: QWord;
844     FTickAll: QWord;
845     FShowOsBarVert: boolean;
846     FShowOsBarHorz: boolean;
847     FMinimapBmp: TBGRABitmap;
848     FMinimapThread: TATMinimapThread;
849     FEventMapStart: TSimpleEvent; //fired when need to start MinimapThread work
850     FEventMapDone: TSimpleEvent; //fired by MinimapThread, when it's work done
851     FColorOfStates: array[TATLineState] of TColor;
852     FFoldingAsStringTodo: string;
853     FHighlightGitConflicts: boolean;
854 
855     //these options are implemented in CudaText, they are dummy here
856     FOptThemed: boolean;
857     FOptAutoPairForMultiCarets: boolean;
858     FOptAutoPairChars: string;
859     FOptAutocompleteAutoshowCharCount: integer;
860     FOptAutocompleteTriggerChars: string;
861     FOptAutocompleteCommitChars: string;
862     FOptAutocompleteCloseChars: string;
863     FOptAutocompleteAddOpeningBracket: boolean;
864     FOptAutocompleteUpDownAtEdge: integer;
865     FOptAutocompleteCommitIfSingleItem: boolean;
866 
867     //options
868     FOptInputNumberOnly: boolean;
869     FOptInputNumberAllowNegative: boolean;
870     FOptMaskChar: WideChar;
871     FOptMaskCharUsed: boolean;
872     FOptScrollAnimationSteps: integer;
873     FOptScrollAnimationSleep: integer;
874     FOptScaleFont: integer;
875     FOptIdleInterval: integer;
876     FOptPasteAtEndMakesFinalEmptyLine: boolean;
877     FOptPasteMultilineTextSpreadsToCarets: boolean;
878     FOptPasteWithEolAtLineStart: boolean;
879     FOptMaxLineLenToTokenize: integer;
880     FOptMinLineLenToCalcURL: integer;
881     FOptMaxLineLenToCalcURL: integer;
882     FOptMaxLinesToCountUnindent: integer;
883     FOptScrollStyleVert: TATEditorScrollbarStyle;
884     FOptScrollStyleHorz: TATEditorScrollbarStyle;
885     FOptScrollSmooth: boolean;
886     FOptScrollIndentCaretHorz: integer; //offsets for caret-moving: if caret goes out of control
887     FOptScrollIndentCaretVert: integer; //must be 0, >0 gives jumps on move-down
888     FOptUndoLimit: integer;
889     FOptUndoGrouped: boolean;
890     FOptUndoMaxCarets: integer;
891     FOptUndoIndentVert: integer;
892     FOptUndoIndentHorz: integer;
893     FOptUndoPause: integer;
894     FOptUndoPause2: integer;
895     FOptUndoPauseHighlightLine: boolean;
896     FOptUndoForCaretJump: boolean;
897     FOptScrollbarsNew: boolean;
898     FOptScrollbarHorizontalAddSpace: integer;
899     FOptScrollLineCommandsKeepCaretOnScreen: boolean;
900     FOptShowFontLigatures: boolean;
901     FOptShowURLs: boolean;
902     FOptShowURLsRegex: string;
903     FOptShowDragDropMarker: boolean;
904     FOptShowDragDropMarkerWidth: integer;
905     FOptShowFoldedMarkWithSelectionBG: boolean;
906     FOptStapleStyle: TATLineStyle;
907     FOptStapleIndent: integer;
908     FOptStapleWidthPercent: integer;
909     FOptStapleHiliteActive: boolean;
910     FOptStapleHiliteActiveAlpha: integer;
911     FOptStapleEdge1: TATEditorStapleEdge;
912     FOptStapleEdge2: TATEditorStapleEdge;
913     FOptStapleIndentConsidersEnd: boolean;
914     FOptMouseEnableAll: boolean;
915     FOptMouseEnableNormalSelection: boolean;
916     FOptMouseEnableColumnSelection: boolean;
917     FOptMouseColumnSelectionWithoutKey: boolean;
918     FOptCaretsPrimitiveColumnSelection: boolean;
919     FOptCaretsAddedToColumnSelection: boolean;
920     FOptCaretPreferLeftSide: boolean;
921     FOptCaretPosAfterPasteColumn: TATEditorPasteCaret;
922     FOptCaretFixAfterRangeFolded: boolean;
923     FOptCaretsMultiToColumnSel: boolean;
924     FOptCaretProximityVert: integer;
925     FOptMarkersSize: integer;
926     FOptShowScrollHint: boolean;
927     FOptTextCenteringCharWidth: integer;
928     FOptTextOffsetLeft: integer;
929     FOptTextOffsetTop: integer;
930     FOptSavingForceFinalEol: boolean;
931     FOptSavingTrimSpaces: boolean;
932     FOptSavingTrimFinalEmptyLines: boolean;
933     FOptIndentSize: integer;
934     FOptIndentKeepsAlign: boolean;
935     FOptIndentMakesWholeLinesSelection: boolean;
936     FOptBorderVisible: boolean;
937     FOptBorderWidth: integer;
938     FOptBorderWidthFocused: integer;
939     FOptBorderWidthMacro: integer;
940     FOptBorderFocusedActive: boolean;
941     FOptBorderMacroRecording: boolean;
942     FOptBorderRounded: boolean;
943     FOptRulerVisible: boolean;
944     FOptRulerNumeration: TATEditorRulerNumeration;
945     FOptRulerHeightPercents: integer;
946     FOptRulerFontSizePercents: integer;
947     FOptRulerMarkSizeCaret: integer;
948     FOptRulerMarkSizeSmall: integer;
949     FOptRulerMarkSizeBig: integer;
950     FOptRulerMarkForAllCarets: boolean;
951     FOptRulerTopIndentPercents: integer;
952     FOptGutterVisible: boolean;
953     FOptGutterPlusSize: integer;
954     FOptGutterShowFoldAlways: boolean;
955     FOptGutterShowFoldLines: boolean;
956     FOptGutterShowFoldLinesAll: boolean;
957     FOptGutterShowFoldLinesForCaret: boolean;
958     FOptGutterIcons: TATEditorGutterIcons;
959     FOptNumbersAutosize: boolean;
960     FOptNumbersAlignment: TAlignment;
961     FOptNumbersStyle: TATEditorNumbersStyle;
962     FOptNumbersShowFirst: boolean;
963     FOptNumbersShowCarets: boolean;
964     FOptNumbersIndentPercents: integer;
965     FOptNonWordChars: atString;
966     FOptAutoIndent: boolean;
967     FOptAutoIndentKind: TATEditorAutoIndentKind;
968     FOptAutoIndentBetterBracketsCurly: boolean;
969     FOptAutoIndentBetterBracketsRound: boolean;
970     FOptAutoIndentBetterBracketsSquare: boolean;
971     FOptAutoIndentRegexRule: string;
972     FOptTabSpaces: boolean;
973     FOptLastLineOnTop: boolean;
974     FOptOverwriteSel: boolean;
975     FOptOverwriteAllowedOnPaste: boolean;
976     FOptKeyBackspaceUnindent: boolean;
977     FOptKeyBackspaceGoesToPrevLine: boolean;
978     FOptKeyPageKeepsRelativePos: boolean;
979     FOptKeyUpDownNavigateWrapped: boolean;
980     FOptKeyUpDownAllowToEdge: boolean;
981     FOptKeyHomeEndNavigateWrapped: boolean;
982     FOptKeyUpDownKeepColumn: boolean;
983     FOptCopyLinesIfNoSel: boolean;
984     FOptCutLinesIfNoSel: boolean;
985     FOptCopyColumnBlockAlignedBySpaces: boolean;
986     FOptShowFullSel: boolean;
987     FOptShowFullHilite: boolean;
988     FOptShowCurLine: boolean;
989     FOptShowCurLineMinimal: boolean;
990     FOptShowCurLineOnlyFocused: boolean;
991     FOptShowCurLineIfWithoutSel: boolean;
992     FOptShowCurColumn: boolean;
993     FOptShowMouseSelFrame: boolean;
994     FOptMouseHideCursor: boolean;
995     FOptMouseClickOpensURL: boolean;
996     FOptMouseClickNumberSelectsLine: boolean;
997     FOptMouseClickNumberSelectsLineWithEOL: boolean;
998     FOptMouse2ClickAction: TATEditorDoubleClickAction;
999     FOptMouse2ClickOpensURL: boolean;
1000     FOptMouse2ClickDragSelectsWords: boolean;
1001     FOptMouse3ClickSelectsLine: boolean;
1002     FOptMouseDragDrop: boolean;
1003     FOptMouseDragDropCopying: boolean;
1004     FOptMouseDragDropCopyingWithState: TShiftStateEnum;
1005     FOptMouseRightClickMovesCaret: boolean;
1006     FOptMouseMiddleClickAction: TATEditorMiddleClickAction;
1007     FOptMouseWheelScrollVert: boolean;
1008     FOptMouseWheelScrollHorz: boolean;
1009     FOptMouseWheelScrollVertSpeed: integer;
1010     FOptMouseWheelScrollHorzSpeed: integer;
1011     FOptMouseWheelScrollHorzWithState: TShiftStateEnum;
1012     FOptMouseWheelZooms: boolean;
1013     FOptMouseWheelZoomsWithState: TShiftStateEnum;
1014     FOptKeyPageUpDownSize: TATEditorPageDownSize;
1015     FOptKeyLeftRightGoToNextLineWithCarets: boolean;
1016     FOptKeyLeftRightSwapSel: boolean;
1017     FOptKeyLeftRightSwapSelAndSelect: boolean;
1018     FOptKeyHomeToNonSpace: boolean;
1019     FOptKeyEndToNonSpace: boolean;
1020     FOptKeyTabIndents: boolean;
1021     FOptKeyTabIndentsVerticalBlock: boolean;
1022     FOptShowIndentLines: boolean;
1023     FOptShowGutterCaretBG: boolean;
1024     FOptAllowRepaintOnTextChange: boolean;
1025     FOptAllowReadOnly: boolean;
1026     FOptZebraActive: boolean;
1027     FOptZebraStep: integer;
1028     FOptZebraAlphaBlend: byte;
1029     FOptDimUnfocusedBack: integer;
1030     {$ifdef LCLGTK2}
1031     FIMSelText: string;
1032     {$endif}
1033 
1034     //
DoCalcForegroundFromAttribsnull1035     function DoCalcForegroundFromAttribs(AX, AY: integer; var AColor: TColor;
1036       var AFontStyles: TFontStyles): boolean;
DoCalcFoldPropsnull1037     function DoCalcFoldProps(AWrapItemIndex: integer; out AProps: TATFoldBarProps): boolean;
CheckInputForNumberOnlynull1038     class function CheckInputForNumberOnly(const S: UnicodeString; X: integer;
1039       ch: WideChar; AllowNegative: boolean): boolean;
1040     procedure ClearSelRectPoints;
1041     procedure ClearMouseDownVariables;
1042     procedure DebugSelRect;
DoCalcLineLennull1043     function DoCalcLineLen(ALineIndex: integer): integer;
1044     procedure DoChangeBookmarks;
1045     procedure DoHandleWheelRecord(const ARec: TATEditorWheelRecord);
1046     procedure FlushEditingChangeEx(AChange: TATLineChangeKind; ALine, AItemCount: integer);
1047     procedure FlushEditingChangeLog(ALine: integer);
GetIndentStringnull1048     function GetIndentString: UnicodeString;
GetActualProximityVertnull1049     function GetActualProximityVert: integer;
GetAttribsnull1050     function GetAttribs: TATMarkers;
1051     procedure GetClientSizes(out W, H: integer);
GetFoldingAsStringnull1052     function GetFoldingAsString: string;
GetMarkersnull1053     function GetMarkers: TATMarkers;
GetDimRangesnull1054     function GetDimRanges: TATDimRanges;
GetHotspotsnull1055     function GetHotspots: TATHotspots;
GetGutterDecornull1056     function GetGutterDecor: TATGutterDecor;
1057     procedure InitFoldbarCache(ACacheStartIndex: integer);
1058     procedure InitLengthArray(var Lens: TATIntArray);
IsCaretFarFromVertEdgenull1059     function IsCaretFarFromVertEdge: boolean;
IsCaretOnVisibleRectnull1060     function IsCaretOnVisibleRect: boolean;
IsInvalidateAllowednull1061     function IsInvalidateAllowed: boolean; inline;
IsNormalLexerActivenull1062     function IsNormalLexerActive: boolean;
1063     procedure SetEditorIndex(AValue: integer);
1064     procedure SetOptScaleFont(AValue: integer);
1065     procedure UpdateGapForms(ABeforePaint: boolean);
1066     procedure UpdateAndWait(AUpdateWrapInfo: boolean; APause: integer);
1067     procedure SetFoldingAsString(const AValue: string);
1068     procedure SetOptShowURLsRegex(const AValue: string);
1069     procedure SetShowOsBarVert(AValue: boolean);
1070     procedure SetShowOsBarHorz(AValue: boolean);
1071     procedure DebugFindWrapIndex;
DoCalcIndentCharsFromPrevLinesnull1072     function DoCalcIndentCharsFromPrevLines(AX, AY: integer): integer;
1073     procedure DoCalcPosColor(AX, AY: integer; var AColor: TColor);
1074     procedure DoCalcLineEntireColor(ALine: integer; AUseColorOfCurrentLine: boolean; out AColor: TColor; out
1075       AColorForced: boolean; AHiliteLineWithSelection: boolean);
1076     procedure DoCaretsApplyShape(var R: TRect; Props: TATCaretShape; W, H: integer);
DoCaretApplyProximityToVertEdgenull1077     function DoCaretApplyProximityToVertEdge(ACaretPos: TPoint;
1078       ACaretCoordY: integer; AProximity, AIndentVert: integer): boolean;
DoCaretApplyProximityToHorzEdgenull1079     function DoCaretApplyProximityToHorzEdge(ACaretCoordX, AProximity,
1080       AIndentHorz: integer): boolean;
1081     procedure DoCaretsAddOnColumnBlock(APos1, APos2: TPoint; const ARect: TRect);
1082     procedure DoCaretsFixForSurrogatePairs(AMoveRight: boolean);
DoCaretsKeepOnScreennull1083     function DoCaretsKeepOnScreen(AMoveDown: boolean): boolean;
1084     procedure DoCaretsAssign(NewCarets: TATCarets);
1085     procedure DoCaretsShift_CaretItem(Caret: TATCaretItem; APosX, APosY, AShiftX,
1086       AShiftY, AShiftBelowX: integer);
1087     procedure DoCaretsShift_MarkerItem(AMarkerObj: TATMarkers;
1088       AMarkerIndex: integer; APosX, APosY, AShiftX, AShiftY,
1089       AShiftBelowX: integer; APosAfter: TPoint);
1090     procedure DoDropText(AndDeleteSelection: boolean);
1091     procedure DoFoldbarClick(ALine: integer);
DoGetFoldedMarkLinesCountnull1092     function DoGetFoldedMarkLinesCount(ALine: integer): integer;
1093     procedure DoHandleRightClick(X, Y: integer);
DoHandleClickEventnull1094     function DoHandleClickEvent(AEvent: TATSynEditClickEvent): boolean;
1095     procedure DoHotspotsExit;
1096     procedure DoHintShow;
1097     procedure DoHintHide;
1098     procedure DoHintShowForBookmark(ALine: integer);
1099     procedure DoMenuGutterFold_AddDynamicItems(Menu: TPopupMenu);
1100     procedure DoMenuGutterFold;
1101     procedure DoMenuText;
1102     procedure DoMinimapClick(APosY: integer);
1103     procedure DoMinimapDrag(APosY: integer);
1104     procedure DoStringsOnChangeEx(Sender: TObject; AChange: TATLineChangeKind; ALine, AItemCount: integer);
1105     procedure DoStringsOnChangeLog(Sender: TObject; ALine: integer);
1106     procedure DoStringsOnProgress(Sender: TObject);
1107     procedure DoStringsOnUndoAfter(Sender: TObject; AX, AY: integer);
1108     procedure DoStringsOnUndoBefore(Sender: TObject; AX, AY: integer);
1109     procedure DoScroll_SetPos(var AScrollInfo: TATEditorScrollInfo; APos: integer);
1110     procedure DoScroll_LineTop(ALine: integer; AUpdate: boolean);
DoScroll_IndentFromBottomnull1111     function DoScroll_IndentFromBottom(AWrapInfoIndex, AIndentVert: integer): boolean;
1112     procedure DoScroll_IndentFromTop(AWrapInfoIndex, AIndentVert: integer); inline;
1113     procedure DoSelectionDeleteColumnBlock;
DoSelect_MultiCaretsLookLikeColumnSelectionnull1114     function DoSelect_MultiCaretsLookLikeColumnSelection: boolean;
1115     procedure DoSelect_NormalSelToColumnSel(out ABegin, AEnd: TPoint);
_IsFocusednull1116     function _IsFocused: boolean;
GetEncodingNamenull1117     function GetEncodingName: string;
1118     procedure SetEncodingName(const AName: string);
GetGapsnull1119     function GetGaps: TATGaps;
GetLastCommandChangedLinesnull1120     function GetLastCommandChangedLines: integer;
GetMinimapActualHeightnull1121     function GetMinimapActualHeight: integer;
GetMinimapSelTopnull1122     function GetMinimapSelTop: integer;
GetMinimap_DraggedPosToWrapIndexnull1123     function GetMinimap_DraggedPosToWrapIndex(APosY: integer): integer;
GetMinimap_ClickedPosToWrapIndexnull1124     function GetMinimap_ClickedPosToWrapIndex(APosY: integer): integer;
GetOptTextOffsetTopnull1125     function GetOptTextOffsetTop: integer;
GetRedoAsStringnull1126     function GetRedoAsString: string;
GetUndoAsStringnull1127     function GetUndoAsString: string;
IsFoldLineNeededBeforeWrapitemnull1128     function IsFoldLineNeededBeforeWrapitem(N: integer): boolean;
IsRepaintNeededOnEnterOrExitnull1129     function IsRepaintNeededOnEnterOrExit: boolean;
1130     procedure MenuFoldFoldAllClick(Sender: TObject);
1131     procedure MenuFoldLevelClick(Sender: TObject);
1132     procedure MenuFoldUnfoldAllClick(Sender: TObject);
1133     procedure MenuFoldPlusMinusClick(Sender: TObject);
1134     procedure FoldedMarkTooltipPaint(Sender: TObject);
1135     procedure FoldedMarkMouseEnter(Sender: TObject);
1136     procedure OnNewScrollbarHorzChanged(Sender: TObject);
1137     procedure OnNewScrollbarVertChanged(Sender: TObject);
1138     procedure DoPartCalc_CreateNew(var AParts: TATLineParts; AOffsetMax,
1139       ALineIndex, ACharIndex: integer; AColorBG: TColor);
1140     procedure DoPartCalc_ApplySelectionOver(var AParts: TATLineParts; AOffsetMax,
1141       ALineIndex, ACharIndex: integer);
1142     procedure DoPartCalc_ApplyAttribsOver(var AParts: TATLineParts; AOffsetMax,
1143       ALineIndex, ACharIndex: integer; AColorBG: TColor);
GetAutoIndentStringnull1144     function GetAutoIndentString(APosX, APosY: integer; AUseIndentRegexRule: boolean): atString;
GetFoldedMarkTextnull1145     function GetFoldedMarkText(ALine: integer): string;
GetModifiednull1146     function GetModified: boolean;
Unfolded_NextLineNumbernull1147     function Unfolded_NextLineNumber(ALine: integer; ADown: boolean): integer;
Unfolded_FirstLineNumbernull1148     function Unfolded_FirstLineNumber: integer;
Unfolded_LastLineNumbernull1149     function Unfolded_LastLineNumber: integer;
GetOneLinenull1150     function GetOneLine: boolean;
GetRedoCountnull1151     function GetRedoCount: integer;
GetLinesFromTopnull1152     function GetLinesFromTop: integer;
GetTextnull1153     function GetText: UnicodeString;
GetUndoAfterSavenull1154     function GetUndoAfterSave: boolean;
GetUndoCountnull1155     function GetUndoCount: integer;
1156     procedure InitAttribs;
1157     procedure InitMarkers;
1158     procedure InitHotspots;
1159     procedure InitDimRanges;
1160     procedure InitGutterDecor;
1161     procedure InitMarkedRange;
1162     procedure InitFoldedMarkList;
1163     procedure InitFoldedMarkTooltip;
1164     procedure InitFoldImageList;
1165     procedure InitMenuStd;
1166     procedure StartTimerDelayedParsing;
IsWrapItemWithCaretnull1167     function IsWrapItemWithCaret(constref AWrapItem: TATWrapItem): boolean;
1168     procedure MenuClick(Sender: TObject);
1169     procedure MenuStdPopup(Sender: TObject);
1170     procedure DoCalcWrapInfos(ALine: integer; AIndentMaximal: integer;
1171       AItems: TATWrapItems; AConsiderFolding: boolean);
1172     procedure DoCalcLineHilite(const AData: TATWrapItem;
1173       out AParts: TATLineParts; ACharsSkipped, ACharsMax: integer;
1174       AColorBG: TColor; AColorForced: boolean; var AColorAfter: TColor;
1175       AMainText: boolean);
DoScaleFontnull1176     function DoScaleFont(AValue: integer): integer;
1177     //select
1178     procedure DoSelectionDeleteOrReset;
1179     procedure DoSelect_ExtendSelectionByLine(AUp: boolean);
1180     procedure DoSelect_CharRange(ACaretIndex: integer; Pnt: TPoint);
1181     procedure DoSelect_WordRange(ACaretIndex: integer; P1, P2: TPoint);
1182     procedure DoSelect_ByDoubleClick(AllowOnlyWordChars: boolean);
1183     procedure DoSelect_Line_ByClick;
1184     procedure DoSelect_ColumnBlock_MoveEndUpDown(var AX, AY: integer; ALineDelta: integer);
TempSel_IsSelectionnull1185     function TempSel_IsSelection: boolean; inline;
TempSel_IsMultilinenull1186     function TempSel_IsMultiline: boolean; inline;
TempSel_IsLineWithSelectionnull1187     function TempSel_IsLineWithSelection(ALine: integer): boolean; inline;
TempSel_IsLineAllSelectednull1188     function TempSel_IsLineAllSelected(ALine: integer): boolean; inline;
TempSel_IsPosSelectednull1189     function TempSel_IsPosSelected(AX, AY: integer): boolean; inline;
TempSel_IsRangeSelectednull1190     function TempSel_IsRangeSelected(AX1, AY1, AX2, AY2: integer): TATRangeSelection; inline;
1191     procedure TempSel_GetRangesInLineAfterPoint(AX, AY: integer; out ARanges: TATSimpleRangeArray); inline;
1192     //paint
1193     procedure PaintEx(ALineNumber: integer);
DoPaintnull1194     function DoPaint(ALineFrom: integer): boolean;
1195     procedure DoPaintBorder(C: TCanvas; AColor: TColor; ABorderWidth: integer; AUseRectMain: boolean);
1196     procedure DoPaintAll(C: TCanvas; ALineFrom: integer);
1197     procedure DoPaintMain(C: TCanvas; ALineFrom: integer);
1198     procedure DoPaintLine(C: TCanvas; ARectLine: TRect; ACharSize: TATEditorCharSize;
1199       var AScrollHorz, AScrollVert: TATEditorScrollInfo;
1200       const AWrapIndex: integer; var ATempParts: TATLineParts);
1201     procedure DoPaintMinimapLine(ARectLine: TRect; ACharSize: TATEditorCharSize;
1202       var AScrollHorz, AScrollVert: TATEditorScrollInfo;
1203       const AWrapIndex: integer; var ATempParts: TATLineParts);
1204     procedure DoPaintGutterOfLine(C: TCanvas; ARect: TRect; ACharSize: TATEditorCharSize;
1205       AWrapIndex: integer);
1206     procedure DoPaintNiceScroll(C: TCanvas);
1207     procedure DoPaintGutterNumber(C: TCanvas; ALineIndex, ACoordTop: integer; ABand: TATGutterItem);
1208     procedure DoPaintMarginLineTo(C: TCanvas; AX, AWidth: integer; AColor: TColor);
1209     procedure DoPaintRuler(C: TCanvas);
1210     procedure DoPaintRulerCaretMark(C: TCanvas; ACaretX: integer);
1211     procedure DoPaintRulerCaretMarks(C: TCanvas);
1212     procedure DoPaintTiming(C: TCanvas);
1213     procedure DoPaintText(C: TCanvas; const ARect: TRect;
1214       const ACharSize: TATEditorCharSize; AWithGutter: boolean;
1215       var AScrollHorz, AScrollVert: TATEditorScrollInfo; ALineFrom: integer);
1216     procedure DoPaintTextFragment(C: TCanvas; const ARect: TRect; ALineFrom,
1217       ALineTo: integer; AConsiderWrapInfo: boolean; AColorBG, AColorBorder: TColor);
1218     procedure DoPaintLineIndent(C: TCanvas; const ARect: TRect; ACharSize: TATEditorCharSize;
1219       ACoordY: integer; AIndentSize: integer; AColorBG: TColor;
1220       AScrollPos: integer; AIndentLines: boolean);
1221     procedure DoPaintMinimapAllToBGRABitmap;
1222     procedure DoPaintMinimapTextToBGRABitmap(const ARect: TRect;
1223       ACharSize: TATEditorCharSize; var AScrollHorz, AScrollVert: TATEditorScrollInfo);
1224     procedure DoPaintMinimapSelToBGRABitmap;
1225     procedure DoPaintMinimapTooltip(C: TCanvas);
1226     procedure DoPaintMicromap(C: TCanvas);
1227     procedure DoPaintMargins(C: TCanvas);
1228     procedure DoPaintGap(C: TCanvas; const ARect: TRect; AGap: TATGapItem);
1229     procedure DoPaintFoldedMark(C: TCanvas;
1230       APosX, APosY, ACoordX, ACoordY: integer;
1231       const AMarkText: string);
1232     procedure DoPaintCarets(C: TCanvas; AWithInvalidate: boolean);
1233     procedure TimerBlinkDisable;
1234     procedure TimerBlinkEnable;
1235     procedure DoPaintSelectedLineBG(C: TCanvas; ACharSize: TATEditorCharSize;
1236       const AVisRect: TRect; APointLeft, APointText: TPoint;
1237       const AWrapItem: TATWrapItem; ALineWidth: integer;
1238       const AScrollHorz: TATEditorScrollInfo);
1239     procedure DoPaintMarkersTo(C: TCanvas);
1240     procedure DoPaintMarkerOfDragDrop(C: TCanvas);
1241     procedure DoPaintGutterPlusMinus(C: TCanvas; AX, AY: integer; APlus: boolean;
1242       ALineColor: TColor);
1243     procedure DoPaintGutterFolding(C: TCanvas; AWrapItemIndex: integer; ACoordX1,
1244       ACoordX2, ACoordY1, ACoordY2: integer);
1245     procedure DoPaintGutterDecor(C: TCanvas; ALine: integer; const ARect: TRect);
1246     procedure DoPaintGutterBandBG(C: TCanvas; AColor: TColor; AX1, AY1, AX2,
1247       AY2: integer; AEntireHeight: boolean);
1248     procedure DoPaintLockedWarning(C: TCanvas);
1249     procedure DoPaintStaple(C: TCanvas; const R: TRect; AColor: TColor);
1250     procedure DoPaintStaples(C: TCanvas; const ARect: TRect; ACharSize: TATEditorCharSize;
1251       const AScrollHorz: TATEditorScrollInfo);
1252     procedure DoPaintTextHintTo(C: TCanvas);
1253     procedure DoPaintMouseSelFrame(C: TCanvas);
1254     //carets
1255     procedure DoCaretsExtend(ADown: boolean; ALines: integer);
GetCaretManyAllowednull1256     function GetCaretManyAllowed: boolean;
DoCaretSwapEdgenull1257     function DoCaretSwapEdge(Item: TATCaretItem; AMoveLeft: boolean): boolean;
1258     //events
1259     procedure DoEventBeforeCalcHilite;
1260     procedure DoEventClickMicromap(AX, AY: integer);
1261     procedure DoEventClickGutter(ABandIndex, ALineNumber: integer);
DoEventCommandnull1262     function DoEventCommand(ACommand: integer; AInvoke: TATEditorCommandInvoke; const AText: string): boolean;
1263     procedure DoEventDrawBookmarkIcon(C: TCanvas; ALineNumber: integer; const ARect: TRect);
1264     procedure DoEventCommandAfter(ACommand: integer; const AText: string);
1265     //
GetEndOfFilePosnull1266     function GetEndOfFilePos: TPoint;
GetMarginStringnull1267     function GetMarginString: string;
GetReadOnlynull1268     function GetReadOnly: boolean;
GetLineTopnull1269     function GetLineTop: integer;
GetColumnLeftnull1270     function GetColumnLeft: integer;
GetTextForClipboardnull1271     function GetTextForClipboard: string;
GetStringsnull1272     function GetStrings: TATStrings;
GetMouseNiceScrollnull1273     function GetMouseNiceScroll: boolean;
1274     procedure SetEnabledSlowEvents(AValue: boolean);
1275     procedure SetCaretBlinkEnabled(AValue: boolean);
1276     procedure SetFoldEnabled(AValue: boolean);
1277     procedure SetFontBold(AValue: TFont);
1278     procedure SetFontBoldItalic(AValue: TFont);
1279     procedure SetFontItalic(AValue: TFont);
1280     procedure SetLastCommandChangedLines(AValue: integer);
1281     procedure SetModified(AValue: boolean);
1282     procedure SetMouseNiceScroll(AValue: boolean);
1283     procedure SetCaretManyAllowed(AValue: boolean);
1284     procedure SetCaretBlinkTime(AValue: integer);
1285     procedure SetSpacingY(AValue: integer);
1286     procedure SetMarginString(const AValue: string);
1287     procedure SetMicromapVisible(AValue: boolean);
1288     procedure SetMinimapVisible(AValue: boolean);
1289     procedure SetOneLine(AValue: boolean);
1290     procedure SetReadOnly(AValue: boolean);
1291     procedure SetLineTop(AValue: integer);
1292     procedure SetColumnLeft(AValue: integer);
1293     procedure SetLinesFromTop(AValue: integer);
1294     procedure SetRedoAsString(const AValue: string);
1295     procedure SetStrings(Obj: TATStrings);
1296     procedure GetRectMain(out R: TRect);
1297     procedure GetRectMinimap(out R: TRect);
1298     procedure GetRectMinimapSel(out R: TRect);
1299     procedure GetRectMicromap(out R: TRect);
1300     procedure GetRectGutter(out R: TRect);
1301     procedure GetRectRuler(out R: TRect);
GetTextOffsetnull1302     function GetTextOffset: TPoint;
GetPageLinesnull1303     function GetPageLines: integer;
GetMinimapScrollPosnull1304     function GetMinimapScrollPos: integer;
1305     procedure SetTabSize(AValue: integer);
1306     procedure SetTabSpaces(AValue: boolean);
1307     procedure SetText(const AValue: UnicodeString);
1308     procedure SetUndoAfterSave(AValue: boolean);
1309     procedure SetUndoAsString(const AValue: string);
1310     procedure SetUndoLimit(AValue: integer);
1311     procedure SetWrapMode(AValue: TATEditorWrapMode);
1312     procedure SetWrapIndented(AValue: boolean);
1313     procedure UpdateScrollbarVert;
1314     procedure UpdateScrollbarHorz;
1315     procedure UpdateSelRectFromPoints(const P1, P2: TPoint);
1316     procedure UpdateInitialVars(C: TCanvas);
1317     procedure UpdateLinksAttribs;
UpdateLinksRegexObjectnull1318     function UpdateLinksRegexObject: boolean;
1319     procedure UpdateTabHelper;
1320     procedure UpdateCursor;
1321     procedure UpdateGutterAutosize;
1322     procedure UpdateMinimapAutosize;
1323     procedure UpdateFoldedMarkTooltip;
1324     procedure UpdateClientSizes;
DoFormatLineNumbernull1325     function DoFormatLineNumber(N: integer): string;
UpdateScrollInfoFromMessagenull1326     function UpdateScrollInfoFromMessage(var Info: TATEditorScrollInfo; const Msg: TLMScroll): boolean;
1327     procedure UpdateCaretsCoords(AOnlyLast: boolean = false);
GetCharSizenull1328     function GetCharSize(C: TCanvas; ACharSpacingY: integer): TATEditorCharSize;
GetScrollbarVisiblenull1329     function GetScrollbarVisible(bVertical: boolean): boolean;
1330     procedure SetMarginRight(AValue: integer);
1331 
1332     //timers
1333     procedure TimerIdleTick(Sender: TObject);
1334     procedure TimerBlinkTick(Sender: TObject);
1335     procedure TimerScrollTick(Sender: TObject);
1336     procedure TimerNiceScrollTick(Sender: TObject);
1337     procedure TimerDelayedParsingTick(Sender: TObject);
1338     procedure TimerFlickerTick(Sender: TObject);
1339 
1340     //carets
1341     procedure DoCaretAddToPoint(AX, AY: integer);
1342     procedure DoCaretsColumnToPoint(AX, AY: integer);
1343     procedure DoCaretsDeleteOnSameLines;
1344 
1345     //editing
IsCommandResults_CaretMovenull1346     function IsCommandResults_CaretMove(Res: TATCommandResults): boolean;
DoCommandCorenull1347     function DoCommandCore(ACmd: integer; const AText: atString): TATCommandResults;
1348     procedure DoCommandResults(ACmd: integer; Res: TATCommandResults);
DoCommand_TextInsertAtCaretsnull1349     function DoCommand_TextInsertAtCarets(const AText: atString; AKeepCaret,
1350       AOvrMode, ASelectThen, AInsertAtLineStarts: boolean): TATCommandResults;
DoCommand_ColumnSelectWithoutKeynull1351     function DoCommand_ColumnSelectWithoutKey(AValue: boolean): TATCommandResults;
DoCommand_FoldLevelnull1352     function DoCommand_FoldLevel(ALevel: integer): TATCommandResults;
DoCommand_FoldAllnull1353     function DoCommand_FoldAll: TATCommandResults;
DoCommand_FoldUnAllnull1354     function DoCommand_FoldUnAll: TATCommandResults;
DoCommand_FoldRangeAtCurLinenull1355     function DoCommand_FoldRangeAtCurLine(ACommand: TATEditorFoldRangeCommand): TATCommandResults;
DoCommand_FoldSelectionnull1356     function DoCommand_FoldSelection: TATCommandResults;
DoCommand_TextTrimSpacesnull1357     function DoCommand_TextTrimSpaces(AMode: TATTrimSpaces): TATCommandResults;
DoCommand_TextChangeCasenull1358     function DoCommand_TextChangeCase(AMode: TATEditorCaseConvert): TATCommandResults;
DoCommand_ScaleDeltanull1359     function DoCommand_ScaleDelta(AIncrease: boolean): TATCommandResults;
DoCommand_ScaleResetnull1360     function DoCommand_ScaleReset: TATCommandResults;
DoCommand_MoveSelectionUpDownnull1361     function DoCommand_MoveSelectionUpDown(ADown: boolean): TATCommandResults;
DoCommand_TextInsertEmptyAboveBelownull1362     function DoCommand_TextInsertEmptyAboveBelow(ADown: boolean): TATCommandResults;
DoCommand_SelectColumnToDirectionnull1363     function DoCommand_SelectColumnToDirection(ADir: TATEditorSelectColumnDirection): TATCommandResults;
DoCommand_SelectColumnToLineEdgenull1364     function DoCommand_SelectColumnToLineEdge(AToEnd: boolean): TATCommandResults;
DoCommand_RemoveOneCaretnull1365     function DoCommand_RemoveOneCaret(AFirstCaret: boolean): TATCommandResults;
DoCommand_TextInsertColumnBlockOncenull1366     function DoCommand_TextInsertColumnBlockOnce(const AText: string; AKeepCaret: boolean): TATCommandResults;
DoCommand_CaretsExtendnull1367     function DoCommand_CaretsExtend(ADown: boolean; ALines: integer): TATCommandResults;
DoCommand_UndoRedonull1368     function DoCommand_UndoRedo(AUndo: boolean): TATCommandResults;
DoCommand_TextIndentUnindentnull1369     function DoCommand_TextIndentUnindent(ARight: boolean): TATCommandResults;
DoCommand_TextIndentUnindent_StreamBlocknull1370     function DoCommand_TextIndentUnindent_StreamBlock(ARight: boolean): TATCommandResults;
1371     procedure DoCommand_TextIndentUnindent_StreamBlock_OneCaret(ARight: boolean; Caret: TATCaretItem);
DoCommand_TextIndentUnindent_ColumnBlocknull1372     function DoCommand_TextIndentUnindent_ColumnBlock(ARight: boolean): TATCommandResults;
DoCommand_SelectWordsnull1373     function DoCommand_SelectWords: TATCommandResults;
DoCommand_SelectLinesnull1374     function DoCommand_SelectLines: TATCommandResults;
DoCommand_SelectAllnull1375     function DoCommand_SelectAll: TATCommandResults;
DoCommand_SelectInvertednull1376     function DoCommand_SelectInverted: TATCommandResults;
DoCommand_SelectSplitToLinesnull1377     function DoCommand_SelectSplitToLines: TATCommandResults;
DoCommand_SelectExtendByLinenull1378     function DoCommand_SelectExtendByLine(AUp: boolean): TATCommandResults;
DoCommand_Cancelnull1379     function DoCommand_Cancel(AKeepLast, AKeepSel: boolean): TATCommandResults;
DoCommand_ToggleReadOnlynull1380     function DoCommand_ToggleReadOnly: TATCommandResults;
DoCommand_ToggleOverwritenull1381     function DoCommand_ToggleOverwrite: TATCommandResults;
DoCommand_ToggleWordWrapnull1382     function DoCommand_ToggleWordWrap(AltOrder: boolean): TATCommandResults;
DoCommand_ToggleUnprintednull1383     function DoCommand_ToggleUnprinted: TATCommandResults;
DoCommand_ToggleUnprintedSpacesnull1384     function DoCommand_ToggleUnprintedSpaces: TATCommandResults;
DoCommand_ToggleUnprintedSpacesTrailingnull1385     function DoCommand_ToggleUnprintedSpacesTrailing: TATCommandResults;
DoCommand_ToggleUnprintedEndsnull1386     function DoCommand_ToggleUnprintedEnds: TATCommandResults;
DoCommand_ToggleUnprintedEndDetailsnull1387     function DoCommand_ToggleUnprintedEndDetails: TATCommandResults;
DoCommand_ToggleLineNumsnull1388     function DoCommand_ToggleLineNums: TATCommandResults;
DoCommand_ToggleFoldingnull1389     function DoCommand_ToggleFolding: TATCommandResults;
DoCommand_ToggleRulernull1390     function DoCommand_ToggleRuler: TATCommandResults;
DoCommand_ToggleMiniMapnull1391     function DoCommand_ToggleMiniMap: TATCommandResults;
DoCommand_ToggleMicroMapnull1392     function DoCommand_ToggleMicroMap: TATCommandResults;
DoCommand_GotoWordnull1393     function DoCommand_GotoWord(AJump: TATWordJump; AJumpSimple: boolean=false): TATCommandResults;
DoCommand_GotoLineEdgenull1394     function DoCommand_GotoLineEdge(ABegin: boolean): TATCommandResults;
DoCommand_GotoScreenSidenull1395     function DoCommand_GotoScreenSide(ASide: TATCaretScreenSide): TATCommandResults;
DoCommand_ScrollToBeginOrEndnull1396     function DoCommand_ScrollToBeginOrEnd(AToBegin: boolean): TATCommandResults;
DoCommand_ScrollByDeltanull1397     function DoCommand_ScrollByDelta(ALines, AColumns: integer; AKeepCaretOnScreen: boolean): TATCommandResults;
DoCommand_ScrollToLeftnull1398     function DoCommand_ScrollToLeft: TATCommandResults;
DoCommand_TextInsertTabSpacesAtCaretsnull1399     function DoCommand_TextInsertTabSpacesAtCarets(AOvrMode: boolean): TATCommandResults;
DoCommand_TextTabulationnull1400     function DoCommand_TextTabulation: TATCommandResults;
DoCommand_KeyHomenull1401     function DoCommand_KeyHome: TATCommandResults;
DoCommand_KeyEndnull1402     function DoCommand_KeyEnd: TATCommandResults;
DoCommand_KeyLeftnull1403     function DoCommand_KeyLeft(ASelCommand: boolean): TATCommandResults;
DoCommand_KeyRightnull1404     function DoCommand_KeyRight(ASelCommand: boolean): TATCommandResults;
DoCommand_KeyUpDownnull1405     function DoCommand_KeyUpDown(ADown: boolean; ALines: integer; AKeepRelativePos: boolean): TATCommandResults;
DoCommand_KeyUpDown_NextLinenull1406     function DoCommand_KeyUpDown_NextLine(ADown: boolean; ALines: integer): TATCommandResults;
DoCommand_KeyUpDown_Wrappednull1407     function DoCommand_KeyUpDown_Wrapped(ADown: boolean; ALines: integer): TATCommandResults;
DoCommand_TextBackspacenull1408     function DoCommand_TextBackspace: TATCommandResults;
DoCommand_TextDeletenull1409     function DoCommand_TextDelete: TATCommandResults;
DoCommand_TextDeleteSelectionnull1410     function DoCommand_TextDeleteSelection: TATCommandResults;
DoCommand_TextDeleteLeftnull1411     function DoCommand_TextDeleteLeft(ALen: integer; AAllowUnindent: boolean): TATCommandResults;
DoCommand_TextDeleteRightnull1412     function DoCommand_TextDeleteRight(ALen: integer): TATCommandResults;
DoCommand_TextInsertEolnull1413     function DoCommand_TextInsertEol(AKeepCaret: boolean): TATCommandResults;
DoCommand_ForceFinalEndOfLinenull1414     function DoCommand_ForceFinalEndOfLine: TATCommandResults;
DoCommand_DeleteFinalEndOfLinenull1415     function DoCommand_DeleteFinalEndOfLine: TATCommandResults;
DoCommand_TextDeleteLinesnull1416     function DoCommand_TextDeleteLines: TATCommandResults;
DoCommand_TextDuplicateLinenull1417     function DoCommand_TextDuplicateLine: TATCommandResults;
DoCommand_TextDeleteToLineBeginnull1418     function DoCommand_TextDeleteToLineBegin: TATCommandResults;
DoCommand_TextDeleteToLineEndnull1419     function DoCommand_TextDeleteToLineEnd: TATCommandResults;
DoCommand_TextDeleteWordnull1420     function DoCommand_TextDeleteWord(ANext: boolean): TATCommandResults;
DoCommand_TextDeleteWordEntirenull1421     function DoCommand_TextDeleteWordEntire: TATCommandResults;
DoCommand_TextDeleteToDocumentBeginnull1422     function DoCommand_TextDeleteToDocumentBegin: TATCommandResults;
DoCommand_TextDeleteToDocumentEndnull1423     function DoCommand_TextDeleteToDocumentEnd: TATCommandResults;
DoCommand_GotoTextBeginnull1424     function DoCommand_GotoTextBegin: TATCommandResults;
DoCommand_GotoTextEndnull1425     function DoCommand_GotoTextEnd: TATCommandResults;
DoCommand_ClipboardPastenull1426     function DoCommand_ClipboardPaste(AKeepCaret, ASelectThen: boolean;
1427       AClipboardObject: TClipboard): TATCommandResults;
DoCommand_ClipboardPasteColumnBlocknull1428     function DoCommand_ClipboardPasteColumnBlock(AKeepCaret: boolean;
1429       AClipboardObject: TClipboard): TATCommandResults;
DoCommand_ClipboardCopynull1430     function DoCommand_ClipboardCopy(Append: boolean;
1431       AClipboardObject: TClipboard): TATCommandResults;
DoCommand_ClipboardCutnull1432     function DoCommand_ClipboardCut(
1433       AClipboardObject: TClipboard): TATCommandResults;
DoCommand_Sortnull1434     function DoCommand_Sort(AAction: TATStringsSortAction): TATCommandResults;
DoCommand_DeleteAllBlanksnull1435     function DoCommand_DeleteAllBlanks: TATCommandResults;
DoCommand_DeleteAdjacentBlanksnull1436     function DoCommand_DeleteAdjacentBlanks: TATCommandResults;
DoCommand_DeleteAdjacentDupsnull1437     function DoCommand_DeleteAdjacentDups: TATCommandResults;
DoCommand_DeleteAllDupsnull1438     function DoCommand_DeleteAllDups(AKeepBlanks: boolean): TATCommandResults;
DoCommand_ReverseLinesnull1439     function DoCommand_ReverseLines: TATCommandResults;
DoCommand_ShuffleLinesnull1440     function DoCommand_ShuffleLines: TATCommandResults;
1441     //
GetCommandFromKeynull1442     function GetCommandFromKey(var Key: Word; Shift: TShiftState): integer;
DoMouseWheelActionnull1443     function DoMouseWheelAction(Shift: TShiftState; AWheelDelta: integer;
1444       AForceHorz: boolean): boolean;
GetCaretsArraynull1445     function GetCaretsArray: TATPointArray;
GetMarkersArraynull1446     function GetMarkersArray: TATInt64Array;
1447     procedure SetCaretsArray(const Ar: TATPointArray);
1448     procedure SetMarkersArray(const Ar: TATInt64Array);
1449     property MouseNiceScroll: boolean read GetMouseNiceScroll write SetMouseNiceScroll;
1450     property ShowOsBarVert: boolean read FShowOsBarVert write SetShowOsBarVert;
1451     property ShowOsBarHorz: boolean read FShowOsBarHorz write SetShowOsBarHorz;
1452 
1453   public
1454     TagString: string; //to store plugin specific data in CudaText
1455     InitialOptions: TATEditorTempOptions;
1456 
1457     IsModifiedWrapMode: boolean;
1458     IsModifiedMinimapVisible: boolean;
1459     IsModifiedMicromapVisible: boolean;
1460     IsModifiedRulerVisible: boolean;
1461     IsModifiedGutterNumbersVisible: boolean;
1462     IsModifiedGutterFoldingVisible: boolean;
1463     IsModifiedGutterBookmarksVisible: boolean;
1464     IsModifiedUnprintedVisible: boolean;
1465     IsModifiedUnprintedSpaces: boolean;
1466     IsModifiedUnprintedTrailingOnly: boolean;
1467     IsModifiedUnprintedEnds: boolean;
1468     IsModifiedUnprintedEndDetails: boolean;
1469 
1470     //overrides
1471     constructor Create(AOwner: TComponent); override;
1472     destructor Destroy; override;
1473     procedure SetFocus; override;
1474     procedure DragDrop(Source: TObject; X, Y: Integer); override;
1475     property ClientWidth: integer read FClientW;
1476     property ClientHeight: integer read FClientH;
1477     //updates
1478     procedure Invalidate; override;
1479     procedure Update(AUpdateWrapInfo: boolean=false); reintroduce;
1480     procedure UpdateWrapInfo(AForceUpdate: boolean=false);
1481     procedure UpdateFoldedFromLinesHidden;
1482     procedure UpdateScrollInfoFromSmoothPos(var AInfo: TATEditorScrollInfo; const APos: Int64);
1483     procedure UpdateFoldLineIndexer;
UpdateScrollbarsnull1484     function UpdateScrollbars(AdjustSmoothPos: boolean): boolean;
1485     procedure DoEventCarets; virtual;
1486     procedure DoEventScroll; virtual;
1487     procedure DoEventChange(ALineIndex: integer=-1; AllowOnChange: boolean=true); virtual;
1488     procedure DoEventState; virtual;
1489     procedure DoEventZoom;
1490     procedure TimersStart;
1491     procedure TimersStop;
1492     //complex props
1493     property Strings: TATStrings read GetStrings write SetStrings;
1494     property Fold: TATSynRanges read FFold;
1495     property Carets: TATCarets read FCarets;
1496     property CaretsSel: TATCaretSelections read FSel; //not used by apps (at 2021.02), but let's publish, to not forget
1497     property Markers: TATMarkers read GetMarkers;
1498     property Attribs: TATMarkers read GetAttribs;
1499     property Micromap: TATMicromap read FMicromap;
1500     property DimRanges: TATDimRanges read GetDimRanges;
1501     property Hotspots: TATHotspots read GetHotspots;
1502     property Gaps: TATGaps read GetGaps;
1503     property Keymap: TATKeymap read FKeymap write FKeymap;
1504     property CommandLog: TATEditorCommandLog read FCommandLog;
1505     property MouseMap: TATEditorMouseActionArray read FMouseActions write FMouseActions;
1506     property TabHelper: TATStringTabHelper read FTabHelper;
1507     property WrapInfo: TATWrapInfo read FWrapInfo;
1508     property ScrollVert: TATEditorScrollInfo read FScrollVert write FScrollVert;
1509     property ScrollHorz: TATEditorScrollInfo read FScrollHorz write FScrollHorz;
1510     property ScrollbarVert: TATScrollbar read FScrollbarVert;
1511     property ScrollbarHorz: TATScrollbar read FScrollbarHorz;
1512     property CudatextFrame: TCustomFrame read FCudatextFrame write FCudatextFrame;
1513     //property BrotherEditor: TATSynEdit read FBrotherEditor write FBrotherEditor;
1514     property CaretShapeNormal: TATCaretShape read FCaretShapeNormal;
1515     property CaretShapeOverwrite: TATCaretShape read FCaretShapeOverwrite;
1516     property CaretShapeReadonly: TATCaretShape read FCaretShapeReadonly;
1517     //common
1518     property EncodingName: string read GetEncodingName write SetEncodingName;
1519     property Modified: boolean read GetModified write SetModified;
1520     property AdapterForHilite: TATAdapterHilite read FAdapterHilite write FAdapterHilite;
1521     property AdapterIME: TATAdapterIME read FAdapterIME write FAdapterIME;
1522     property EditorIndex: integer read FEditorIndex write SetEditorIndex;
1523     property LineTop: integer read GetLineTop write SetLineTop;
1524     property LineBottom: integer read FLineBottom;
1525     property LinesFromTop: integer read GetLinesFromTop write SetLinesFromTop;
1526     property ColumnLeft: integer read GetColumnLeft write SetColumnLeft;
1527     property ModeOverwrite: boolean read FOverwrite write FOverwrite;
1528     property ModeReadOnly: boolean read GetReadOnly write SetReadOnly;
1529     property ModeOneLine: boolean read GetOneLine write SetOneLine;
1530     property ModeMacroRecording: boolean read FIsMacroRecording write FIsMacroRecording;
1531     property UndoCount: integer read GetUndoCount;
1532     property RedoCount: integer read GetRedoCount;
1533     property UndoAsString: string read GetUndoAsString write SetUndoAsString;
1534     property RedoAsString: string read GetRedoAsString write SetRedoAsString;
1535     procedure ActionAddJumpToUndo;
1536     property Text: UnicodeString read GetText write SetText;
1537     property SelRect: TRect read FSelRect;
1538     function IsSelRectEmpty: boolean;
1539     function IsSelColumn: boolean;
1540     function IsPosSelected(AX, AY: integer): boolean;
1541     function IsRangeSelected(AX1, AY1, AX2, AY2: integer): TATRangeSelection;
1542     function IsPosFolded(AX, AY: integer): boolean;
1543     function IsPosInVisibleArea(AX, AY: integer): boolean;
1544     function IsLineFolded(ALine: integer; ADetectPartialFold: boolean = false): boolean;
1545     function IsCharWord(ch: Widechar): boolean;
1546     property TextCharSize: TATEditorCharSize read FCharSize;
1547     procedure DoUnfoldLine(ALine: integer);
1548     property RectMain: TRect read FRectMain;
1549     property RectGutter: TRect read FRectGutter;
1550     property RectMinimap: TRect read FRectMinimap;
1551     property RectMicromap: TRect read FRectMicromap;
1552     property RectRuler: TRect read FRectRuler;
1553     function RectMicromapMark(AColumn, ALineFrom, ALineTo: integer;
1554       AMapHeight, AMinMarkHeight: integer): TRect;
1555     property OptTextOffsetLeft: integer read FOptTextOffsetLeft write FOptTextOffsetLeft;
1556     property OptTextOffsetTop: integer read GetOptTextOffsetTop write FOptTextOffsetTop;
1557     //gutter
1558     property Gutter: TATGutter read FGutter;
1559     property GutterDecor: TATGutterDecor read GetGutterDecor;
1560     property GutterDecorAlignment: TAlignment read FGutterDecorAlignment write FGutterDecorAlignment;
1561     property GutterBandBookmarks: integer read FGutterBandBookmarks write FGutterBandBookmarks;
1562     property GutterBandNumbers: integer read FGutterBandNumbers write FGutterBandNumbers;
1563     property GutterBandStates: integer read FGutterBandStates write FGutterBandStates;
1564     property GutterBandFolding: integer read FGutterBandFolding write FGutterBandFolding;
1565     property GutterBandSeparator: integer read FGutterBandSeparator write FGutterBandSeparator;
1566     property GutterBandEmpty: integer read FGutterBandEmpty write FGutterBandEmpty;
1567     property GutterBandDecor: integer read FGutterBandDecor write FGutterBandDecor;
1568     //files
1569     property FileName: string read FFileName write FFileName;
1570     procedure LoadFromFile(const AFilename: string; AKeepScroll: boolean=false); virtual;
1571     procedure SaveToFile(const AFilename: string); virtual;
1572     //cmd
1573     procedure TextInsertAtCarets(const AText: atString; AKeepCaret,
1574       AOvrMode, ASelectThen: boolean);
1575     //carets
1576     procedure DoCaretSingle(APosX, APosY, AEndX, AEndY: integer);
1577     procedure DoCaretSingle(AX, AY: integer; AClearSelection: boolean = true);
1578     procedure DoCaretSingleAsIs;
1579     function DoCaretsFixIncorrectPos(AndLimitByLineEnds: boolean): boolean;
1580     procedure DoCaretsFixIfInsideFolded;
1581     procedure DoCaretsShift(AFromCaret: integer; APosX, APosY: integer; AShiftX, AShiftY: integer;
1582       APosAfter: TPoint; AShiftBelowX: integer = 0);
1583     procedure DoCaretForceShow;
1584     function CaretPosToClientPos(P: TPoint): TPoint;
1585     function ClientPosToCaretPos(P: TPoint;
1586       out ADetails: TATEditorPosDetails;
1587       AGapCoordAction: TATEditorGapCoordAction=cGapCoordToLineEnd): TPoint;
1588     function IsLineWithCaret(ALine: integer; ADisableSelected: boolean=false): boolean;
1589     function OffsetToCaretPos(const APos: integer): TPoint;
1590     function CaretPosToOffset(const ACaret: TPoint): integer;
1591     //goto
1592     function DoShowPos(const APos: TPoint; AIndentHorz, AIndentVert: integer;
1593       AUnfold, AllowUpdate, AllowProximity: boolean): boolean;
1594     procedure DoGotoPos(const APos, APosEnd: TPoint;
1595       AIndentHorz, AIndentVert: integer;
1596       APlaceCaret, ADoUnfold: boolean;
1597       AAllowProcessMsg: boolean=true;
1598       AAllowUpdate: boolean=true;
1599       AAllowProximity: boolean=true);
1600     procedure DoGotoCaret(AEdge: TATCaretEdge; AUndoRedo: boolean=false;
1601       AAllowProcessMsg: boolean=true; AAllowUpdate: boolean=true;
1602       AAllowProximity: boolean=true);
1603     //bookmarks
1604     procedure BookmarkSetForLineEx(ALine, ABmKind: integer;
1605       const AHint: string; AAutoDelete: TATBookmarkAutoDelete; AShowInList: boolean; const ATag: Int64;
1606       ABookmarksObj: TATBookmarks);
1607     procedure BookmarkSetForLine(ALine, ABmKind: integer;
1608       const AHint: string; AAutoDelete: TATBookmarkAutoDelete; AShowInList: boolean; const ATag: Int64);
1609     procedure BookmarkSetForLine_2(ALine, ABmKind: integer;
1610       const AHint: string; AAutoDelete: TATBookmarkAutoDelete; AShowInList: boolean; const ATag: Int64);
1611     procedure BookmarkToggleForLine(ALine, ABmKind: integer;
1612       const AHint: string; AAutoDelete: TATBookmarkAutoDelete; AShowInList: boolean; const ATag: Int64);
1613     procedure BookmarkDeleteForLineEx(ALine: integer; ABookmarksObj: TATBookmarks);
1614     procedure BookmarkDeleteForLine(ALine: integer);
1615     procedure BookmarkDeleteForLine_2(ALine: integer);
1616     function BookmarkDeleteByTagEx(const ATag: Int64; ABookmarksObj: TATBookmarks): boolean;
1617     function BookmarkDeleteByTag(const ATag: Int64): boolean;
1618     function BookmarkDeleteByTag_2(const ATag: Int64): boolean;
1619     procedure BookmarkDeleteAll(AWithEvent: boolean=true);
1620     procedure BookmarkDeleteAll_2;
1621     procedure BookmarkInvertAll;
1622     procedure BookmarkGotoNext(ANext: boolean; AIndentHorz, AIndentVert: integer; AOnlyShownInList: boolean);
1623     procedure BookmarkCopyMarkedLines;
1624     procedure BookmarkDeleteMarkedLines;
1625     procedure BookmarkPlaceBookmarksOnCarets;
1626     procedure BookmarkPlaceCaretsOnBookmarks;
1627     //fold
1628     procedure DoRangeFold(ARangeIndex: integer);
1629     procedure DoRangeUnfold(ARangeIndex: integer);
1630     procedure DoRangeHideLines(ALineFrom, ALineTo: integer); inline;
1631     procedure DoFoldForLevel(ALevel: integer);
1632     procedure DoFoldForLevelEx(ALevel: integer; AOuterRange: integer);
1633     procedure DoFoldUnfoldRangeAtCurLine(AOp: TATEditorFoldRangeCommand);
1634     property FoldingAsString: string read GetFoldingAsString write SetFoldingAsString;
1635     property FoldingAsStringTodo: string read FFoldingAsStringTodo write FFoldingAsStringTodo;
1636     //markers
1637     procedure MarkerClearAll;
1638     procedure MarkerDrop;
1639     procedure MarkerGotoLast(AndDelete: boolean; AIndentHorz, AIndentVert: integer);
1640     procedure MarkerSwap;
1641     procedure MarkerSelectToCaret;
1642     procedure MarkerDeleteToCaret;
1643     //menu
1644     property PopupTextDefault: TPopupMenu read FMenuStd;
1645     property PopupText: TPopupMenu read FMenuText write FMenuText;
1646     property PopupGutterBm: TPopupMenu read FMenuGutterBm write FMenuGutterBm;
1647     property PopupGutterNum: TPopupMenu read FMenuGutterNum write FMenuGutterNum;
1648     property PopupGutterFold: TPopupMenu read FMenuGutterFold write FMenuGutterFold;
1649     property PopupMinimap: TPopupMenu read FMenuMinimap write FMenuMinimap;
1650     property PopupMicromap: TPopupMenu read FMenuMicromap write FMenuMicromap;
1651     property PopupRuler: TPopupMenu read FMenuRuler write FMenuRuler;
1652     //misc
1653     function GetVisibleLines: integer;
1654     function GetVisibleColumns: integer;
1655     function GetVisibleLinesMinimap: integer;
1656     procedure DoCommand(ACmd: integer; AInvoke: TATEditorCommandInvoke; const AText: atString = ''); virtual;
1657     procedure BeginUpdate;
1658     procedure EndUpdate;
1659     procedure BeginEditing;
1660     procedure EndEditing(ATextChanged: boolean);
1661     procedure DoHideAllTooltips;
1662     function IsLocked: boolean;
1663     function TextSelected: atString;
1664     function TextSelectedEx(ACaret: TATCaretItem): atString;
1665     function TextCurrentWord: atString;
1666     //LastCommandChangedLines: count of lines changed by last call of Strings.ActionTrimSpaces
1667     property LastCommandChangedLines: integer read GetLastCommandChangedLines write SetLastCommandChangedLines;
1668     property IsRunningCommand: boolean read FIsRunningCommand;
1669     property IsReadOnlyChanged: boolean read FIsReadOnlyChanged write FIsReadOnlyChanged;
1670     property IsReadOnlyAutodetected: boolean read FIsReadOnlyAutodetected write FIsReadOnlyAutodetected;
1671     property IsCaretShapeChangedFromAPI: boolean read FIsCaretShapeChangedFromAPI write FIsCaretShapeChangedFromAPI;
1672     procedure DoSelect_All;
1673     procedure DoSelect_None;
1674     procedure DoSelect_Inverted;
1675     procedure DoSelect_SplitSelectionToLines;
1676     procedure DoSelect_Line(APos: TPoint);
1677     procedure DoSelect_CharGroupAtPos(P: TPoint; AddCaret, AllowOnlyWordChars: boolean);
1678     procedure DoSelect_LineRange(ALineFrom: integer; APosTo: TPoint);
1679     procedure DoSelect_ClearColumnBlock;
1680     procedure DoSelect_ColumnBlock_FromPoints(P1Char, P2Char: TPoint;
1681       AUpdateSelRectPoints: boolean=true);
1682     procedure DoSelect_ColumnBlock_FromPointsColumns(P1, P2: TPoint);
1683     procedure DoSelect_ColumnBlock_Primitive(P1, P2: TPoint);
1684     procedure DoScrollToBeginOrEnd(AToBegin: boolean);
1685     procedure DoScrollByDelta(ADeltaX, ADeltaY: integer);
1686     procedure DoScrollByDeltaInPixels(ADeltaX, ADeltaY: integer);
1687     procedure DoScaleFontDelta(AInc: boolean; AllowUpdate: boolean);
1688     function DoCalcLineHiliteEx(ALineIndex: integer; var AParts: TATLineParts;
1689       AColorBG: TColor; out AColorAfter: TColor): boolean;
1690     procedure DoSetMarkedLines(ALine1, ALine2: integer);
1691     procedure DoGetMarkedLines(out ALine1, ALine2: integer);
1692     function DoGetLinkAtPos(AX, AY: integer): atString;
1693     function DoGetGapRect(AIndex: integer; out ARect: TRect): boolean;
1694     procedure DoConvertIndentation(ASpacesToTabs: boolean);
1695     procedure DoConvertTabsToSpaces;
1696 
1697   protected
1698     IsRepaintEnabled: boolean;
1699     procedure Paint; override;
1700     procedure Resize; override;
1701     procedure DoContextPopup(MousePos: TPoint; var Handled: Boolean); override;
1702     procedure UTF8KeyPress(var UTF8Key: TUTF8Char); override;
1703     procedure KeyDown(var Key: Word; Shift: TShiftState); override;
1704     procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
1705     procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
1706     procedure MouseMove(Shift: TShiftState; X,Y: Integer); override;
1707     procedure MouseLeave; override;
1708 
1709     function DoMouseWheel(Shift: TShiftState; WheelDelta: integer; MousePos{%H-}: TPoint): boolean; override;
1710     function DoMouseWheelHorz(Shift: TShiftState; WheelDelta: integer; MousePos{%H-}: TPoint): boolean; {$IF LCL_FULLVERSION >= 1090000} override; {$ENDIF}
1711 
1712     procedure DblClick; override;
1713     procedure TripleClick; override;
1714     function DoGetTextString: atString; virtual;
1715     procedure DoEnter; override;
1716     procedure DoExit; override;
1717     procedure DragOver(Source: TObject; X, Y: Integer; State: TDragState;
1718       var Accept: Boolean); override;
1719     //messages
1720     //procedure WMGetDlgCode(var Msg: TLMNoParams); message LM_GETDLGCODE;
1721     procedure WMEraseBkgnd(var Msg: TLMEraseBkgnd); message LM_ERASEBKGND;
1722     procedure WMHScroll(var Msg: TLMHScroll); message LM_HSCROLL;
1723     procedure WMVScroll(var Msg: TLMVScroll); message LM_VSCROLL;
1724     procedure CMWantSpecialKey(var Message: TCMWantSpecialKey); message CM_WANTSPECIALKEY;
1725 
1726     {$ifdef windows}
1727     procedure WMIME_Request(var Msg: TMessage); message WM_IME_REQUEST;
1728     procedure WMIME_Notify(var Msg: TMessage); message WM_IME_NOTIFY;
1729     procedure WMIME_StartComposition(var Msg:TMessage); message WM_IME_STARTCOMPOSITION;
1730     procedure WMIME_Composition(var Msg:TMessage); message WM_IME_COMPOSITION;
1731     procedure WMIME_EndComposition(var Msg:TMessage); message WM_IME_ENDCOMPOSITION;
1732     {$endif}
1733 
1734     {$ifdef GTK2_IME_CODE}
1735     procedure WM_GTK_IM_COMPOSITION(var Message: TLMessage); message LM_IM_COMPOSITION;
1736     {$endif}
1737 
1738   published
1739     property Align;
1740     property Anchors;
1741     property BorderSpacing;
1742     property BorderStyle;
1743     property Constraints;
1744     property DoubleBuffered;
1745     property DragMode;
1746     property DragKind;
1747     property Enabled;
1748     property Font;
1749     property FontItalic: TFont read FFontItalic write SetFontItalic;
1750     property FontBold: TFont read FFontBold write SetFontBold;
1751     property FontBoldItalic: TFont read FFontBoldItalic write SetFontBoldItalic;
1752     property ParentFont;
1753     property ParentShowHint;
1754     property ShowHint;
1755     property TabOrder;
1756     property TabStop;
1757     property Visible;
1758     //events std
1759     property OnContextPopup;
1760     property OnDragOver;
1761     property OnDragDrop;
1762     property OnEnter;
1763     property OnExit;
1764     property OnKeyDown;
1765     property OnKeyPress;
1766     property OnKeyUp;
1767     property OnMouseDown;
1768     property OnMouseEnter;
1769     property OnMouseLeave;
1770     property OnMouseMove;
1771     property OnMouseUp;
1772     property OnMouseWheel;
1773     property OnMouseWheelDown;
1774     property OnMouseWheelUp;
1775     property OnResize;
1776     property OnUTF8KeyPress;
1777     //events new
1778     property OnClickDouble: TATSynEditClickEvent read FOnClickDbl write FOnClickDbl;
1779     property OnClickTriple: TATSynEditClickEvent read FOnClickTriple write FOnClickTriple;
1780     property OnClickMiddle: TATSynEditClickEvent read FOnClickMiddle write FOnClickMiddle;
1781     property OnClickGutter: TATSynEditClickGutterEvent read FOnClickGutter write FOnClickGutter;
1782     property OnClickMicromap: TATSynEditClickMicromapEvent read FOnClickMicromap write FOnClickMicromap;
1783     property OnClickMoveCaret: TATSynEditClickMoveCaretEvent read FOnClickMoveCaret write FOnClickMoveCaret;
1784     property OnClickEndSelect: TATSynEditClickMoveCaretEvent read FOnClickEndSelect write FOnClickEndSelect;
1785     property OnClickGap: TATSynEditClickGapEvent read FOnClickGap write FOnClickGap;
1786     property OnClickLink: TATSynEditClickLinkEvent read FOnClickLink write FOnClickLink;
1787     property OnCheckInput: TATSynEditCheckInputEvent read FOnCheckInput write FOnCheckInput;
1788     property OnIdle: TNotifyEvent read FOnIdle write FOnIdle;
1789     property OnChange: TNotifyEvent read FOnChange write FOnChange;
1790     property OnChangeLog: TATStringsChangeLogEvent read FOnChangeLog write FOnChangeLog;
1791     property OnChangeModified: TNotifyEvent read FOnChangeModified write FOnChangeModified;
1792     property OnChangeCaretPos: TNotifyEvent read FOnChangeCaretPos write FOnChangeCaretPos;
1793     property OnChangeState: TNotifyEvent read FOnChangeState write FOnChangeState;
1794     property OnChangeZoom: TNotifyEvent read FOnChangeZoom write FOnChangeZoom;
1795     property OnChangeBookmarks: TNotifyEvent read FOnChangeBookmarks write FOnChangeBookmarks;
1796     property OnScroll: TNotifyEvent read FOnScroll write FOnScroll;
1797     property OnCommand: TATSynEditCommandEvent read FOnCommand write FOnCommand;
1798     property OnCommandAfter: TATSynEditCommandAfterEvent read FOnCommandAfter write FOnCommandAfter;
1799     property OnDrawBookmarkIcon: TATSynEditDrawBookmarkEvent read FOnDrawBookmarkIcon write FOnDrawBookmarkIcon;
1800     property OnDrawLine: TATSynEditDrawLineEvent read FOnDrawLine write FOnDrawLine;
1801     property OnDrawGap: TATSynEditDrawGapEvent read FOnDrawGap write FOnDrawGap;
1802     property OnDrawMicromap: TATSynEditDrawRectEvent read FOnDrawMicromap write FOnDrawMicromap;
1803     property OnDrawEditor: TATSynEditDrawRectEvent read FOnDrawEditor write FOnDrawEditor;
1804     property OnDrawRuler: TATSynEditDrawRectEvent read FOnDrawRuler write FOnDrawRuler;
1805     property OnCalcHilite: TATSynEditCalcHiliteEvent read FOnCalcHilite write FOnCalcHilite;
1806     property OnCalcStaple: TATSynEditCalcStapleEvent read FOnCalcStaple write FOnCalcStaple;
1807     property OnCalcTabSize: TATStringTabCalcEvent read FOnCalcTabSize write FOnCalcTabSize;
1808     property OnCalcBookmarkColor: TATSynEditCalcBookmarkColorEvent read FOnCalcBookmarkColor write FOnCalcBookmarkColor;
1809     property OnBeforeCalcHilite: TNotifyEvent read FOnBeforeCalcHilite write FOnBeforeCalcHilite;
1810     property OnPaste: TATSynEditPasteEvent read FOnPaste write FOnPaste;
1811     property OnHotspotEnter: TATSynEditHotspotEvent read FOnHotspotEnter write FOnHotspotEnter;
1812     property OnHotspotExit: TATSynEditHotspotEvent read FOnHotspotExit write FOnHotspotExit;
1813 
1814     //misc
1815     property CursorText: TCursor read FCursorText write FCursorText default crIBeam;
1816     property CursorColumnSel: TCursor read FCursorColumnSel write FCursorColumnSel default crCross;
1817     property CursorGutterBookmark: TCursor read FCursorGutterBookmark write FCursorGutterBookmark default crHandPoint;
1818     property CursorGutterNumbers: TCursor read FCursorGutterNumbers write FCursorGutterNumbers default crDefault;
1819     property CursorMinimap: TCursor read FCursorMinimap write FCursorMinimap default crDefault;
1820     property CursorMicromap: TCursor read FCursorMicromap write FCursorMicromap default crDefault;
1821     property Colors: TATEditorColors read FColors write FColors stored false;
1822     property ImagesGutterDecor: TImageList read FGutterDecorImages write FGutterDecorImages;
1823     property WantTabs: boolean read FWantTabs write FWantTabs default true;
1824     property WantReturns: boolean read FWantReturns write FWantReturns default true;
1825 
1826     //options
1827     property OptThemed: boolean read FOptThemed write FOptThemed default false;
1828     property OptHighlightGitConflicts: boolean read FHighlightGitConflicts write FHighlightGitConflicts default cInitHighlightGitConflicts;
1829     property OptAutoPairForMultiCarets: boolean read FOptAutoPairForMultiCarets write FOptAutoPairForMultiCarets default cInitAutoPairForMultiCarets;
1830     property OptAutoPairChars: string read FOptAutoPairChars write FOptAutoPairChars stored false;
1831     property OptAutocompleteAutoshowCharCount: integer read FOptAutocompleteAutoshowCharCount write FOptAutocompleteAutoshowCharCount default 0;
1832     property OptAutocompleteTriggerChars: string read FOptAutocompleteTriggerChars write FOptAutocompleteTriggerChars stored false;
1833     property OptAutocompleteCommitChars: string read FOptAutocompleteCommitChars write FOptAutocompleteCommitChars stored false;
1834     property OptAutocompleteCloseChars: string read FOptAutocompleteCloseChars write FOptAutocompleteCloseChars stored false;
1835     property OptAutocompleteAddOpeningBracket: boolean read FOptAutocompleteAddOpeningBracket write FOptAutocompleteAddOpeningBracket default true;
1836     property OptAutocompleteUpDownAtEdge: integer read FOptAutocompleteUpDownAtEdge write FOptAutocompleteUpDownAtEdge default 1;
1837     property OptAutocompleteCommitIfSingleItem: boolean read FOptAutocompleteCommitIfSingleItem write FOptAutocompleteCommitIfSingleItem default false;
1838 
1839     property OptInputNumberOnly: boolean read FOptInputNumberOnly write FOptInputNumberOnly default false;
1840     property OptInputNumberAllowNegative: boolean read FOptInputNumberAllowNegative write FOptInputNumberAllowNegative default cInitInputNumberAllowNegative;
1841     property OptMaskChar: WideChar read FOptMaskChar write FOptMaskChar default cInitMaskChar;
1842     property OptMaskCharUsed: boolean read FOptMaskCharUsed write FOptMaskCharUsed default false;
1843     property OptScrollAnimationSteps: integer read FOptScrollAnimationSteps write FOptScrollAnimationSteps default cInitScrollAnimationSteps;
1844     property OptScrollAnimationSleep: integer read FOptScrollAnimationSleep write FOptScrollAnimationSleep default cInitScrollAnimationSleep;
1845     property OptScaleFont: integer read FOptScaleFont write SetOptScaleFont default 0;
1846     property OptIdleInterval: integer read FOptIdleInterval write FOptIdleInterval default cInitIdleInterval;
1847     property OptTabSpaces: boolean read FOptTabSpaces write SetTabSpaces default false;
1848     property OptTabSize: integer read FTabSize write SetTabSize default cInitTabSize;
1849     property OptNonWordChars: atString read FOptNonWordChars write FOptNonWordChars stored false;
1850     property OptFoldStyle: TATEditorFoldStyle read FFoldStyle write FFoldStyle default cInitFoldStyle;
1851     property OptFoldEnabled: boolean read FFoldEnabled write SetFoldEnabled default true;
1852     property OptFoldCacheEnabled: boolean read FFoldCacheEnabled write FFoldCacheEnabled default true;
1853     property OptFoldUnderlineOffset: integer read FFoldUnderlineOffset write FFoldUnderlineOffset default cInitFoldUnderlineOffset;
1854     property OptFoldTooltipVisible: boolean read FFoldTooltipVisible write FFoldTooltipVisible default cInitFoldTooltipVisible;
1855     property OldFoldTooltipWidthPercents: integer read FFoldTooltipWidthPercents write FFoldTooltipWidthPercents default cInitFoldTooltipWidthPercents;
1856     property OptFoldTooltipLineCount: integer read FFoldTooltipLineCount write FFoldTooltipLineCount default cInitFoldTooltipLineCount;
1857     property OptTextHint: string read FTextHint write FTextHint;
1858     property OptTextHintFontStyle: TFontStyles read FTextHintFontStyle write FTextHintFontStyle default [fsItalic];
1859     property OptTextHintCenter: boolean read FTextHintCenter write FTextHintCenter default false;
1860     property OptTextCenteringCharWidth: integer read FOptTextCenteringCharWidth write FOptTextCenteringCharWidth default 0;
1861     property OptAutoIndent: boolean read FOptAutoIndent write FOptAutoIndent default true;
1862     property OptAutoIndentKind: TATEditorAutoIndentKind read FOptAutoIndentKind write FOptAutoIndentKind default cIndentAsPrevLine;
1863     property OptAutoIndentBetterBracketsCurly: boolean read FOptAutoIndentBetterBracketsCurly write FOptAutoIndentBetterBracketsCurly default true;
1864     property OptAutoIndentBetterBracketsRound: boolean read FOptAutoIndentBetterBracketsRound write FOptAutoIndentBetterBracketsRound default false;
1865     property OptAutoIndentBetterBracketsSquare: boolean read FOptAutoIndentBetterBracketsSquare write FOptAutoIndentBetterBracketsSquare default false;
1866     property OptAutoIndentRegexRule: string read FOptAutoIndentRegexRule write FOptAutoIndentRegexRule;
1867     property OptCopyLinesIfNoSel: boolean read FOptCopyLinesIfNoSel write FOptCopyLinesIfNoSel default true;
1868     property OptCutLinesIfNoSel: boolean read FOptCutLinesIfNoSel write FOptCutLinesIfNoSel default false;
1869     property OptCopyColumnBlockAlignedBySpaces: boolean read FOptCopyColumnBlockAlignedBySpaces write FOptCopyColumnBlockAlignedBySpaces default true;
1870     property OptLastLineOnTop: boolean read FOptLastLineOnTop write FOptLastLineOnTop default false;
1871     property OptOverwriteSel: boolean read FOptOverwriteSel write FOptOverwriteSel default true;
1872     property OptOverwriteAllowedOnPaste: boolean read FOptOverwriteAllowedOnPaste write FOptOverwriteAllowedOnPaste default false;
1873     property OptScrollStyleHorz: TATEditorScrollbarStyle read FOptScrollStyleHorz write FOptScrollStyleHorz default aessAuto;
1874     property OptScrollStyleVert: TATEditorScrollbarStyle read FOptScrollStyleVert write FOptScrollStyleVert default aessShow;
1875     property OptScrollSmooth: boolean read FOptScrollSmooth write FOptScrollSmooth default true;
1876     property OptScrollIndentCaretHorz: integer read FOptScrollIndentCaretHorz write FOptScrollIndentCaretHorz default 10;
1877     property OptScrollIndentCaretVert: integer read FOptScrollIndentCaretVert write FOptScrollIndentCaretVert default 0;
1878     property OptScrollbarsNew: boolean read FOptScrollbarsNew write FOptScrollbarsNew default false;
1879     property OptScrollbarHorizontalAddSpace: integer read FOptScrollbarHorizontalAddSpace write FOptScrollbarHorizontalAddSpace default cInitScrollbarHorzAddSpace;
1880     property OptScrollLineCommandsKeepCaretOnScreen: boolean read FOptScrollLineCommandsKeepCaretOnScreen write FOptScrollLineCommandsKeepCaretOnScreen default true;
1881 
1882     property OptShowFontLigatures: boolean read FOptShowFontLigatures write FOptShowFontLigatures default true;
1883     property OptShowURLs: boolean read FOptShowURLs write FOptShowURLs default true;
1884     property OptShowURLsRegex: string read FOptShowURLsRegex write SetOptShowURLsRegex stored false;
1885     property OptShowDragDropMarker: boolean read FOptShowDragDropMarker write FOptShowDragDropMarker default true;
1886     property OptShowDragDropMarkerWidth: integer read FOptShowDragDropMarkerWidth write FOptShowDragDropMarkerWidth default cInitDragDropMarkerWidth;
1887     property OptShowFoldedMarkWithSelectionBG: boolean read FOptShowFoldedMarkWithSelectionBG write FOptShowFoldedMarkWithSelectionBG default cInitShowFoldedMarkWithSelectionBG;
1888     property OptMaxLineLenToTokenize: integer read FOptMaxLineLenToTokenize write FOptMaxLineLenToTokenize default cInitMaxLineLenToTokenize;
1889     property OptMinLineLenToCalcURL: integer read FOptMinLineLenToCalcURL write FOptMinLineLenToCalcURL default cInitMinLineLenToCalcURL;
1890     property OptMaxLineLenToCalcURL: integer read FOptMaxLineLenToCalcURL write FOptMaxLineLenToCalcURL default cInitMaxLineLenToCalcURL;
1891     property OptMaxLinesToCountUnindent: integer read FOptMaxLinesToCountUnindent write FOptMaxLinesToCountUnindent default 100;
1892     property OptStapleStyle: TATLineStyle read FOptStapleStyle write FOptStapleStyle default cLineStyleSolid;
1893     property OptStapleIndent: integer read FOptStapleIndent write FOptStapleIndent default -1;
1894     property OptStapleWidthPercent: integer read FOptStapleWidthPercent write FOptStapleWidthPercent default 100;
1895     property OptStapleHiliteActive: boolean read FOptStapleHiliteActive write FOptStapleHiliteActive default true;
1896     property OptStapleHiliteActiveAlpha: integer read FOptStapleHiliteActiveAlpha write FOptStapleHiliteActiveAlpha default cInitStapleHiliteAlpha;
1897     property OptStapleEdge1: TATEditorStapleEdge read FOptStapleEdge1 write FOptStapleEdge1 default cStapleEdgeAngle;
1898     property OptStapleEdge2: TATEditorStapleEdge read FOptStapleEdge2 write FOptStapleEdge2 default cStapleEdgeAngle;
1899     property OptStapleIndentConsidersEnd: boolean read FOptStapleIndentConsidersEnd write FOptStapleIndentConsidersEnd default false;
1900     property OptShowFullWidthForSelection: boolean read FOptShowFullSel write FOptShowFullSel default false;
1901     property OptShowFullWidthForSyntaxHilite: boolean read FOptShowFullHilite write FOptShowFullHilite default true;
1902     property OptShowCurLine: boolean read FOptShowCurLine write FOptShowCurLine default false;
1903     property OptShowCurLineMinimal: boolean read FOptShowCurLineMinimal write FOptShowCurLineMinimal default true;
1904     property OptShowCurLineOnlyFocused: boolean read FOptShowCurLineOnlyFocused write FOptShowCurLineOnlyFocused default false;
1905     property OptShowCurLineIfWithoutSel: boolean read FOptShowCurLineIfWithoutSel write FOptShowCurLineIfWithoutSel default true;
1906     property OptShowCurColumn: boolean read FOptShowCurColumn write FOptShowCurColumn default false;
1907     property OptShowScrollHint: boolean read FOptShowScrollHint write FOptShowScrollHint default false;
1908     property OptShowMouseSelFrame: boolean read FOptShowMouseSelFrame write FOptShowMouseSelFrame default cInitShowMouseSelFrame;
1909     property OptCaretManyAllowed: boolean read GetCaretManyAllowed write SetCaretManyAllowed default true;
1910     property OptCaretVirtual: boolean read FCaretVirtual write FCaretVirtual default true;
1911     property OptCaretBlinkTime: integer read FCaretBlinkTime write SetCaretBlinkTime default cInitCaretBlinkTime;
1912     property OptCaretBlinkEnabled: boolean read FCaretBlinkEnabled write SetCaretBlinkEnabled default true;
1913     property OptCaretStopUnfocused: boolean read FCaretStopUnfocused write FCaretStopUnfocused default true;
1914     property OptCaretHideUnfocused: boolean read FCaretHideUnfocused write FCaretHideUnfocused default true;
1915     property OptCaretPreferLeftSide: boolean read FOptCaretPreferLeftSide write FOptCaretPreferLeftSide default true;
1916     property OptCaretPosAfterPasteColumn: TATEditorPasteCaret read FOptCaretPosAfterPasteColumn write FOptCaretPosAfterPasteColumn default cPasteCaretColumnRight;
1917     property OptCaretsPrimitiveColumnSelection: boolean read FOptCaretsPrimitiveColumnSelection write FOptCaretsPrimitiveColumnSelection default cInitCaretsPrimitiveColumnSelection;
1918     property OptCaretsAddedToColumnSelection: boolean read FOptCaretsAddedToColumnSelection write FOptCaretsAddedToColumnSelection default true;
1919     property OptCaretFixAfterRangeFolded: boolean read FOptCaretFixAfterRangeFolded write FOptCaretFixAfterRangeFolded default true;
1920     property OptCaretsMultiToColumnSel: boolean read FOptCaretsMultiToColumnSel write FOptCaretsMultiToColumnSel default cInitCaretsMultiToColumnSel;
1921     property OptCaretProximityVert: integer read FOptCaretProximityVert write FOptCaretProximityVert default 0;
1922     property OptMarkersSize: integer read FOptMarkersSize write FOptMarkersSize default cInitMarkerSize;
1923     property OptGutterVisible: boolean read FOptGutterVisible write FOptGutterVisible default true;
1924     property OptGutterPlusSize: integer read FOptGutterPlusSize write FOptGutterPlusSize default cInitGutterPlusSize;
1925     property OptGutterShowFoldAlways: boolean read FOptGutterShowFoldAlways write FOptGutterShowFoldAlways default true;
1926     property OptGutterShowFoldLines: boolean read FOptGutterShowFoldLines write FOptGutterShowFoldLines default true;
1927     property OptGutterShowFoldLinesAll: boolean read FOptGutterShowFoldLinesAll write FOptGutterShowFoldLinesAll default false;
1928     property OptGutterShowFoldLinesForCaret: boolean read FOptGutterShowFoldLinesForCaret write FOptGutterShowFoldLinesForCaret default true;
1929     property OptGutterIcons: TATEditorGutterIcons read FOptGutterIcons write FOptGutterIcons default cGutterIconsPlusMinus;
1930     property OptBorderVisible: boolean read FOptBorderVisible write FOptBorderVisible default cInitBorderVisible;
1931     property OptBorderWidth: integer read FOptBorderWidth write FOptBorderWidth default cInitBorderWidth;
1932     property OptBorderWidthFocused: integer read FOptBorderWidthFocused write FOptBorderWidthFocused default cInitBorderWidthFocused;
1933     property OptBorderWidthMacro: integer read FOptBorderWidthMacro write FOptBorderWidthMacro default cInitBorderWidthMacro;
1934     property OptBorderRounded: boolean read FOptBorderRounded write FOptBorderRounded default false;
1935     property OptBorderFocusedActive: boolean read FOptBorderFocusedActive write FOptBorderFocusedActive default false;
1936     property OptBorderMacroRecording: boolean read FOptBorderMacroRecording write FOptBorderMacroRecording default true;
1937     property OptRulerVisible: boolean read FOptRulerVisible write FOptRulerVisible default true;
1938     property OptRulerNumeration: TATEditorRulerNumeration read FOptRulerNumeration write FOptRulerNumeration default cInitRulerNumeration;
1939     property OptRulerHeightPercents: integer read FOptRulerHeightPercents write FOptRulerHeightPercents default cSizeRulerHeightPercents;
1940     property OptRulerFontSizePercents: integer read FOptRulerFontSizePercents write FOptRulerFontSizePercents default 80;
1941     property OptRulerMarkSizeCaret: integer read FOptRulerMarkSizeCaret write FOptRulerMarkSizeCaret default cSizeRulerMarkCaret;
1942     property OptRulerMarkSizeSmall: integer read FOptRulerMarkSizeSmall write FOptRulerMarkSizeSmall default cSizeRulerMarkSmall;
1943     property OptRulerMarkSizeBig: integer read FOptRulerMarkSizeBig write FOptRulerMarkSizeBig default cSizeRulerMarkBig;
1944     property OptRulerMarkForAllCarets: boolean read FOptRulerMarkForAllCarets write FOptRulerMarkForAllCarets default false;
1945     property OptRulerTopIndentPercents: integer read FOptRulerTopIndentPercents write FOptRulerTopIndentPercents default 0;
1946     property OptMinimapCustomScale: integer read FMinimapCustomScale write FMinimapCustomScale default 0;
1947     property OptMinimapVisible: boolean read FMinimapVisible write SetMinimapVisible default cInitMinimapVisible;
1948     property OptMinimapCharWidth: integer read FMinimapCharWidth write FMinimapCharWidth default 0;
1949     property OptMinimapShowSelBorder: boolean read FMinimapShowSelBorder write FMinimapShowSelBorder default false;
1950     property OptMinimapShowSelAlways: boolean read FMinimapShowSelAlways write FMinimapShowSelAlways default true;
1951     property OptMinimapSelColorChange: integer read FMinimapSelColorChange write FMinimapSelColorChange default cInitMinimapSelColorChange;
1952     property OptMinimapAtLeft: boolean read FMinimapAtLeft write FMinimapAtLeft default false;
1953     property OptMinimapTooltipVisible: boolean read FMinimapTooltipVisible write FMinimapTooltipVisible default cInitMinimapTooltipVisible;
1954     property OptMinimapTooltipLinesCount: integer read FMinimapTooltipLinesCount write FMinimapTooltipLinesCount default cInitMinimapTooltipLinesCount;
1955     property OptMinimapTooltipWidthPercents: integer read FMinimapTooltipWidthPercents write FMinimapTooltipWidthPercents default cInitMinimapTooltipWidthPercents;
1956     property OptMinimapHiliteLinesWithSelection: boolean read FMinimapHiliteLinesWithSelection write FMinimapHiliteLinesWithSelection default true;
1957     property OptMinimapDragImmediately: boolean read FMinimapDragImmediately write FMinimapDragImmediately default false;
1958     property OptMicromapVisible: boolean read FMicromapVisible write SetMicromapVisible default cInitMicromapVisible;
1959     property OptMicromapOnScrollbar: boolean read FMicromapOnScrollbar write FMicromapOnScrollbar default cInitMicromapOnScrollbar;
1960     property OptMicromapLineStates: boolean read FMicromapLineStates write FMicromapLineStates default true;
1961     property OptMicromapSelections: boolean read FMicromapSelections write FMicromapSelections default true;
1962     property OptMicromapBookmarks: boolean read FMicromapBookmarks write FMicromapBookmarks default cInitMicromapBookmarks;
1963     property OptMicromapShowForMinCount: integer read FMicromapShowForMinCount write FMicromapShowForMinCount default cInitMicromapShowForMinCount;
1964     property OptSpacingY: integer read FSpacingY write SetSpacingY default cInitSpacingY;
1965     property OptWrapMode: TATEditorWrapMode read FWrapMode write SetWrapMode default cInitWrapMode;
1966     property OptWrapIndented: boolean read FWrapIndented write SetWrapIndented default true;
1967     property OptWrapAddSpace: integer read FWrapAddSpace write FWrapAddSpace default 1;
1968     property OptWrapEnabledForMaxLines: integer read FWrapEnabledForMaxLines write FWrapEnabledForMaxLines default cInitWrapEnabledForMaxLines;
1969     property OptMarginRight: integer read FMarginRight write SetMarginRight default cInitMarginRight;
1970     property OptMarginString: string read GetMarginString write SetMarginString;
1971     property OptNumbersAutosize: boolean read FOptNumbersAutosize write FOptNumbersAutosize default true;
1972     property OptNumbersAlignment: TAlignment read FOptNumbersAlignment write FOptNumbersAlignment default taRightJustify;
1973     property OptNumbersStyle: TATEditorNumbersStyle read FOptNumbersStyle write FOptNumbersStyle default cInitNumbersStyle;
1974     property OptNumbersShowFirst: boolean read FOptNumbersShowFirst write FOptNumbersShowFirst default true;
1975     property OptNumbersShowCarets: boolean read FOptNumbersShowCarets write FOptNumbersShowCarets default false;
1976     property OptNumbersIndentPercents: integer read FOptNumbersIndentPercents write FOptNumbersIndentPercents default cInitNumbersIndentPercents;
1977     property OptUnprintedVisible: boolean read FUnprintedVisible write FUnprintedVisible default true;
1978     property OptUnprintedSpaces: boolean read FUnprintedSpaces write FUnprintedSpaces default true;
1979     property OptUnprintedSpacesTrailing: boolean read FUnprintedSpacesTrailing write FUnprintedSpacesTrailing default false;
1980     property OptUnprintedSpacesBothEnds: boolean read FUnprintedSpacesBothEnds write FUnprintedSpacesBothEnds default false;
1981     property OptUnprintedSpacesOnlyInSelection: boolean read FUnprintedSpacesOnlyInSelection write FUnprintedSpacesOnlyInSelection default false;
1982     property OptUnprintedEnds: boolean read FUnprintedEnds write FUnprintedEnds default true;
1983     property OptUnprintedEndsDetails: boolean read FUnprintedEndsDetails write FUnprintedEndsDetails default true;
1984     property OptUnprintedEof: boolean read FUnprintedEof write FUnprintedEof default true;
1985     property OptMouseEnableAll: boolean read FOptMouseEnableAll write FOptMouseEnableAll default true;
1986     property OptMouseEnableNormalSelection: boolean read FOptMouseEnableNormalSelection write FOptMouseEnableNormalSelection default true;
1987     property OptMouseEnableColumnSelection: boolean read FOptMouseEnableColumnSelection write FOptMouseEnableColumnSelection default true;
1988     property OptMouseHideCursorOnType: boolean read FOptMouseHideCursor write FOptMouseHideCursor default false;
1989     property OptMouseClickOpensURL: boolean read FOptMouseClickOpensURL write FOptMouseClickOpensURL default false;
1990     property OptMouseClickNumberSelectsLine: boolean read FOptMouseClickNumberSelectsLine write FOptMouseClickNumberSelectsLine default true;
1991     property OptMouseClickNumberSelectsLineWithEOL: boolean read FOptMouseClickNumberSelectsLineWithEOL write FOptMouseClickNumberSelectsLineWithEOL default true;
1992     property OptMouse2ClickAction: TATEditorDoubleClickAction read FOptMouse2ClickAction write FOptMouse2ClickAction default cMouseDblClickSelectAnyChars;
1993     property OptMouse2ClickOpensURL: boolean read FOptMouse2ClickOpensURL write FOptMouse2ClickOpensURL default true;
1994     property OptMouse2ClickDragSelectsWords: boolean read FOptMouse2ClickDragSelectsWords write FOptMouse2ClickDragSelectsWords default true;
1995     property OptMouse3ClickSelectsLine: boolean read FOptMouse3ClickSelectsLine write FOptMouse3ClickSelectsLine default true;
1996     property OptMouseDragDrop: boolean read FOptMouseDragDrop write FOptMouseDragDrop default true;
1997     property OptMouseDragDropCopying: boolean read FOptMouseDragDropCopying write FOptMouseDragDropCopying default true;
1998     property OptMouseDragDropCopyingWithState: TShiftStateEnum read FOptMouseDragDropCopyingWithState write FOptMouseDragDropCopyingWithState default ssModifier;
1999     property OptMouseMiddleClickAction: TATEditorMiddleClickAction read FOptMouseMiddleClickAction write FOptMouseMiddleClickAction default mcaScrolling;
2000     property OptMouseRightClickMovesCaret: boolean read FOptMouseRightClickMovesCaret write FOptMouseRightClickMovesCaret default false;
2001     property OptMouseWheelScrollVert: boolean read FOptMouseWheelScrollVert write FOptMouseWheelScrollVert default true;
2002     property OptMouseWheelScrollVertSpeed: integer read FOptMouseWheelScrollVertSpeed write FOptMouseWheelScrollVertSpeed default 3;
2003     property OptMouseWheelScrollHorz: boolean read FOptMouseWheelScrollHorz write FOptMouseWheelScrollHorz default true;
2004     property OptMouseWheelScrollHorzSpeed: integer read FOptMouseWheelScrollHorzSpeed write FOptMouseWheelScrollHorzSpeed default 10;
2005     property OptMouseWheelScrollHorzWithState: TShiftStateEnum read FOptMouseWheelScrollHorzWithState write FOptMouseWheelScrollHorzWithState default ssShift;
2006     property OptMouseWheelZooms: boolean read FOptMouseWheelZooms write FOptMouseWheelZooms default true;
2007     property OptMouseWheelZoomsWithState: TShiftStateEnum read FOptMouseWheelZoomsWithState write FOptMouseWheelZoomsWithState default ssModifier;
2008     property OptMouseColumnSelectionWithoutKey: boolean read FOptMouseColumnSelectionWithoutKey write FOptMouseColumnSelectionWithoutKey default false;
2009     property OptKeyBackspaceUnindent: boolean read FOptKeyBackspaceUnindent write FOptKeyBackspaceUnindent default true;
2010     property OptKeyBackspaceGoesToPrevLine: boolean read FOptKeyBackspaceGoesToPrevLine write FOptKeyBackspaceGoesToPrevLine default true;
2011     property OptKeyPageKeepsRelativePos: boolean read FOptKeyPageKeepsRelativePos write FOptKeyPageKeepsRelativePos default true;
2012     property OptKeyUpDownNavigateWrapped: boolean read FOptKeyUpDownNavigateWrapped write FOptKeyUpDownNavigateWrapped default true;
2013     property OptKeyUpDownAllowToEdge: boolean read FOptKeyUpDownAllowToEdge write FOptKeyUpDownAllowToEdge default false;
2014     property OptKeyUpDownKeepColumn: boolean read FOptKeyUpDownKeepColumn write FOptKeyUpDownKeepColumn default true;
2015     property OptKeyHomeEndNavigateWrapped: boolean read FOptKeyHomeEndNavigateWrapped write FOptKeyHomeEndNavigateWrapped default true;
2016     property OptKeyPageUpDownSize: TATEditorPageDownSize read FOptKeyPageUpDownSize write FOptKeyPageUpDownSize default cPageSizeFullMinus1;
2017     property OptKeyLeftRightGoToNextLineWithCarets: boolean read FOptKeyLeftRightGoToNextLineWithCarets write FOptKeyLeftRightGoToNextLineWithCarets default true;
2018     property OptKeyLeftRightSwapSel: boolean read FOptKeyLeftRightSwapSel write FOptKeyLeftRightSwapSel default true;
2019     property OptKeyLeftRightSwapSelAndSelect: boolean read FOptKeyLeftRightSwapSelAndSelect write FOptKeyLeftRightSwapSelAndSelect default false;
2020     property OptKeyHomeToNonSpace: boolean read FOptKeyHomeToNonSpace write FOptKeyHomeToNonSpace default true;
2021     property OptKeyEndToNonSpace: boolean read FOptKeyEndToNonSpace write FOptKeyEndToNonSpace default true;
2022     property OptKeyTabIndents: boolean read FOptKeyTabIndents write FOptKeyTabIndents default true;
2023     property OptKeyTabIndentsVerticalBlock: boolean read FOptKeyTabIndentsVerticalBlock write FOptKeyTabIndentsVerticalBlock default false;
2024     property OptIndentSize: integer read FOptIndentSize write FOptIndentSize default 2;
2025              // N>0: use N spaces
2026              // N<0: use N tabs
2027              // N=0: calc indent from OptTabSize/OptTabSpaces
2028     property OptIndentKeepsAlign: boolean read FOptIndentKeepsAlign write FOptIndentKeepsAlign default true;
2029     property OptIndentMakesWholeLinesSelection: boolean read FOptIndentMakesWholeLinesSelection write FOptIndentMakesWholeLinesSelection default false;
2030     property OptShowIndentLines: boolean read FOptShowIndentLines write FOptShowIndentLines default true;
2031     property OptShowGutterCaretBG: boolean read FOptShowGutterCaretBG write FOptShowGutterCaretBG default true;
2032     property OptAllowRepaintOnTextChange: boolean read FOptAllowRepaintOnTextChange write FOptAllowRepaintOnTextChange default true;
2033     property OptAllowReadOnly: boolean read FOptAllowReadOnly write FOptAllowReadOnly default true;
2034     property OptUndoLimit: integer read FOptUndoLimit write SetUndoLimit default cInitUndoLimit;
2035     property OptUndoGrouped: boolean read FOptUndoGrouped write FOptUndoGrouped default true;
2036     property OptUndoAfterSave: boolean read GetUndoAfterSave write SetUndoAfterSave default true;
2037     property OptUndoMaxCarets: integer read FOptUndoMaxCarets write FOptUndoMaxCarets default cInitUndoMaxCarets;
2038     property OptUndoIndentVert: integer read FOptUndoIndentVert write FOptUndoIndentVert default cInitUndoIndentVert;
2039     property OptUndoIndentHorz: integer read FOptUndoIndentHorz write FOptUndoIndentHorz default cInitUndoIndentHorz;
2040     property OptUndoPause: integer read FOptUndoPause write FOptUndoPause default cInitUndoPause;
2041     property OptUndoPause2: integer read FOptUndoPause2 write FOptUndoPause2 default cInitUndoPause2;
2042     property OptUndoPauseHighlightLine: boolean read FOptUndoPauseHighlightLine write FOptUndoPauseHighlightLine default cInitUndoPauseHighlightLine;
2043     property OptUndoForCaretJump: boolean read FOptUndoForCaretJump write FOptUndoForCaretJump default cInitUndoForCaretJump;
2044     property OptSavingForceFinalEol: boolean read FOptSavingForceFinalEol write FOptSavingForceFinalEol default false;
2045     property OptSavingTrimSpaces: boolean read FOptSavingTrimSpaces write FOptSavingTrimSpaces default false;
2046     property OptSavingTrimFinalEmptyLines: boolean read FOptSavingTrimFinalEmptyLines write FOptSavingTrimFinalEmptyLines default false;
2047     property OptPasteAtEndMakesFinalEmptyLine: boolean read FOptPasteAtEndMakesFinalEmptyLine write FOptPasteAtEndMakesFinalEmptyLine default true;
2048     property OptPasteMultilineTextSpreadsToCarets: boolean read FOptPasteMultilineTextSpreadsToCarets write FOptPasteMultilineTextSpreadsToCarets default true;
2049     property OptPasteWithEolAtLineStart: boolean read FOptPasteWithEolAtLineStart write FOptPasteWithEolAtLineStart default true;
2050     property OptZebraActive: boolean read FOptZebraActive write FOptZebraActive default false;
2051     property OptZebraStep: integer read FOptZebraStep write FOptZebraStep default 2;
2052     property OptZebraAlphaBlend: byte read FOptZebraAlphaBlend write FOptZebraAlphaBlend default cInitZebraAlphaBlend;
2053     property OptDimUnfocusedBack: integer read FOptDimUnfocusedBack write FOptDimUnfocusedBack default cInitDimUnfocusedBack;
2054   end;
2055 
2056 const
2057   cEncNameUtf8_WithBom = 'UTF-8 with BOM';
2058   cEncNameUtf8_NoBom = 'UTF-8';
2059   cEncNameUtf16LE_WithBom = 'UTF-16 LE with BOM';
2060   cEncNameUtf16LE_NoBom = 'UTF-16 LE';
2061   cEncNameUtf16BE_WithBom = 'UTF-16 BE with BOM';
2062   cEncNameUtf16BE_NoBom = 'UTF-16 BE';
2063   cEncNameUtf32LE_WithBom = 'UTF-32 LE with BOM';
2064   cEncNameUtf32LE_NoBom = 'UTF-32 LE';
2065   cEncNameUtf32BE_WithBom = 'UTF-32 BE with BOM';
2066   cEncNameUtf32BE_NoBom = 'UTF-32 BE';
2067 
2068 function EditorLinkIsEmail(const S: string): boolean;
2069 procedure EditorOpenLink(const S: string);
2070 
2071 implementation
2072 
2073 uses
2074   LCLIntf,
2075   LCLProc,
2076   Dialogs,
2077   Types,
2078   Math,
2079   {$ifdef LCLGTK2}
2080   gtk2,
2081   Gtk2Globals,
2082   {$endif}
2083   ATStringProc_TextBuffer,
2084   ATSynEdit_Commands,
2085   ATSynEdit_Keymap_Init;
2086 
2087 {$I atsynedit_proc.inc}
2088 
2089 { TATMinimapThread }
2090 
2091 procedure TATMinimapThread.Execute;
2092 var
2093   Ed: TATSynEdit;
2094 begin
2095   Ed:= TATSynEdit(Editor);
2096   repeat
2097     if Terminated then exit;
2098     if Ed.FEventMapStart.WaitFor(1000)=wrSignaled then
2099     begin
2100       Ed.FEventMapStart.ResetEvent;
2101       Ed.DoPaintMinimapAllToBGRABitmap;
2102       Ed.FEventMapDone.SetEvent;
2103     end;
2104   until false;
2105 end;
2106 
2107 { TATSynEdit }
2108 
2109 procedure TATSynEdit.DoPaintRuler(C: TCanvas);
2110 var
2111   NCoordX, NPrevFontSize, NRulerStart, NOutput,
2112   NTopIndent, NMarkHeight, i: integer;
2113   NCharWidthScaled: integer;
2114   Str: string;
2115 begin
2116   NPrevFontSize:= C.Font.Size;
2117   NRulerStart:= FScrollHorz.NPos;
2118   NTopIndent:= FOptRulerTopIndentPercents*FCharSize.Y div 100;
2119 
2120   C.Font.Name:= Font.Name;
2121   C.Font.Size:= DoScaleFont(Font.Size) * FOptRulerFontSizePercents div 100;
2122   C.Font.Color:= Colors.RulerFont;
2123   C.Pen.Color:= Colors.RulerFont;
2124   C.Brush.Color:= Colors.RulerBG;
2125 
2126   C.FillRect(FRectRuler);
2127 
2128   NCharWidthScaled:= FCharSize.XScaled * FOptRulerFontSizePercents div 100;
2129 
2130   for i:= NRulerStart to NRulerStart+FVisibleColumns+1 do
2131   begin
2132     NCoordX:= FRectMain.Left + (i-NRulerStart) * FCharSize.XScaled div ATEditorCharXScale;
2133 
2134     case FOptRulerNumeration of
2135       cRulerNumeration_0_10_20:
2136         begin
2137           NOutput:= i;
2138           if (i mod 10 = 0) then
2139           begin
2140             Str:= IntToStr(NOutput);
2141             CanvasTextOutSimplest(C, NCoordX - NCharWidthScaled*Length(Str) div 2 div ATEditorCharXScale, NTopIndent, Str);
2142           end;
2143         end;
2144       cRulerNumeration_1_11_21:
2145         begin
2146           NOutput:= i;
2147           if (i mod 10 = 0) then
2148           begin
2149             Str:= IntToStr(NOutput+1{!});
2150             CanvasTextOutSimplest(C, NCoordX - NCharWidthScaled*Length(Str) div 2 div ATEditorCharXScale, NTopIndent, Str);
2151           end;
2152         end;
2153       cRulerNumeration_1_10_20:
2154         begin
2155           NOutput:= i+1;
2156           if (NOutput=1) or (NOutput mod 10 = 0) then
2157           begin
2158             Str:= IntToStr(NOutput);
2159             CanvasTextOutSimplest(C, NCoordX - NCharWidthScaled*Length(Str) div 2 div ATEditorCharXScale, NTopIndent, Str);
2160           end;
2161         end;
2162     end;
2163 
2164     if NOutput mod 5 = 0 then
2165       NMarkHeight:= EditorScale(FOptRulerMarkSizeBig)
2166     else
2167       NMarkHeight:= EditorScale(FOptRulerMarkSizeSmall);
2168 
2169     CanvasLineVert(C, NCoordX, FRectRuler.Bottom-1-NMarkHeight, FRectRuler.Bottom-1);
2170   end;
2171 
2172   CanvasLineHorz(C, FRectRuler.Left, FRectRuler.Bottom-1, FRectRuler.Right);
2173 
2174   C.Font.Size:= NPrevFontSize;
2175 end;
2176 
2177 
2178 procedure TATSynEdit.DoPaintRulerCaretMark(C: TCanvas; ACaretX: integer);
2179 begin
2180   if (ACaretX>=FRectRuler.Left) and (ACaretX<FRectRuler.Right) then
2181     CanvasPaintTriangleDown(C,
2182       Colors.RulerFont,
2183       Point(ACaretX, FRectRuler.Top+EditorScale(FOptRulerMarkSizeCaret)),
2184       EditorScale(FOptRulerMarkSizeCaret)
2185       );
2186 end;
2187 
2188 procedure TATSynEdit.DoPaintRulerCaretMarks(C: TCanvas);
2189 var
2190   NCount, i: integer;
2191 begin
2192   if FOptRulerVisible and (FOptRulerMarkSizeCaret>0) then
2193   begin
2194     if FOptRulerMarkForAllCarets then
2195       NCount:= Carets.Count
2196     else
2197       NCount:= 1;
2198 
2199     for i:= 0 to NCount-1 do
2200       DoPaintRulerCaretMark(C, Carets[i].CoordX);
2201   end;
2202 end;
2203 
2204 procedure TATSynEdit.UpdateGutterAutosize;
2205 var
2206   Str: string;
2207 begin
2208   Str:= IntToStr(Max(10, Strings.Count));
2209   FGutter[FGutterBandNumbers].Size:=
2210     Length(Str)*FCharSize.XScaled div ATEditorCharXScale + 2*FNumbersIndent;
2211   FGutter.Update;
2212 end;
2213 
2214 procedure TATSynEdit.UpdateMinimapAutosize;
2215 {
2216   Minimap must give same cnt of small chars, as rest width gives for normal chars.
2217   This gives:
2218     MapSize / CharWidth_small = (ClientWidth - MapSize) / CharWidth_big
2219     MapSize = (ClientWidth * CharWidth_small) / (CharWidth_big+CharWidth_small)
2220 }
2221 var
2222   CharSmall, CharBig: integer;
2223 begin
2224   CharBig:= FCharSize.XScaled div ATEditorCharXScale;
2225   CharSmall:= FCharSizeMinimap.XScaled div ATEditorCharXScale;
2226 
2227   if FMinimapCharWidth=0 then
2228   begin
2229     FMinimapWidth:= ClientWidth-FTextOffset.X;
2230     if FMicromapVisible and not FMicromapOnScrollbar then
2231       Dec(FMinimapWidth, FRectMicromap.Width);
2232     FMinimapWidth:= FMinimapWidth * CharSmall div (CharSmall+CharBig);
2233   end
2234   else
2235     FMinimapWidth:= CharSmall*FMinimapCharWidth;
2236 
2237   FMinimapWidth:= Max(cMinMinimapWidth, FMinimapWidth);
2238 end;
2239 
DoFormatLineNumbernull2240 function TATSynEdit.DoFormatLineNumber(N: integer): string;
2241 var
2242   NCurLine: integer;
2243 begin
2244   if FOptNumbersStyle=cNumbersRelative then
2245   begin
2246     if Carets.Count=0 then
2247       exit(IntToStr(N));
2248     NCurLine:= Carets[0].PosY+1;
2249     if N=NCurLine then
2250       Result:= IntToStr(N)
2251     else
2252       Result:= IntToStr(N-NCurLine);
2253     exit
2254   end;
2255 
2256   if FOptNumbersShowCarets then
2257     if IsLineWithCaret(N-1) then
2258       Exit(IntToStr(N));
2259 
2260   if FOptNumbersShowFirst then
2261     if N=1 then
2262       Exit(IntToStr(N));
2263 
2264   case FOptNumbersStyle of
2265     cNumbersAll:
2266       Result:= IntToStr(N);
2267     cNumbersNone:
2268       Result:= '.';
2269     cNumbersEach10th:
2270       begin
2271         if (N mod 10 = 0) then
2272           Result:= IntToStr(N)
2273         else
2274         if (N mod 5) = 0 then
2275           Result:= '-'
2276         else
2277           Result:= '.';
2278       end;
2279     cNumbersEach5th:
2280       begin
2281         if (N mod 5 = 0) then
2282           Result:= IntToStr(N)
2283         else
2284           Result:= '.';
2285       end;
2286   end;
2287 end;
2288 
GetScrollbarVisiblenull2289 function TATSynEdit.GetScrollbarVisible(bVertical: boolean): boolean;
2290 const
2291   cKind: array[boolean] of integer = (SB_HORZ, SB_VERT);
2292 var
2293   si: TScrollInfo;
2294 begin
2295   FillChar(si{%H-}, SizeOf(si), 0);
2296   si.cbSize:= SizeOf(si);
2297   si.fMask:= SIF_ALL;
2298   GetScrollInfo(Handle, cKind[bVertical], si);
2299   Result:= Longword(si.nMax) > Longword(si.nPage);
2300 end;
2301 
2302 procedure TATSynEdit.SetMarginRight(AValue: integer);
2303 begin
2304   if AValue=FMarginRight then Exit;
2305   FMarginRight:= Max(AValue, cMinMarginRt);
2306   if FWrapMode in [cWrapAtMargin, cWrapAtWindowOrMargin] then
2307     FWrapUpdateNeeded:= true;
2308 end;
2309 
2310 procedure TATSynEdit.UpdateWrapInfo(AForceUpdate: boolean);
2311 var
2312   CurStrings: TATStrings;
2313   ListNums: TATIntegerList;
2314   UseCachedUpdate: boolean;
2315   bConsiderFolding: boolean;
2316   NNewVisibleColumns: integer;
2317   NIndentMaximal: integer;
2318   NLine, NIndexFrom, NIndexTo: integer;
2319   i, j: integer;
2320 begin
2321   //method can be called before 1st paint,
2322   //so TCanvas.TextWidth (TATSynEdit.GetCharSize) will give exception "Control has no parent window"
2323   //example: CudaText has user.json with "wrap_mode":1
2324 
2325   //2021.01.29:
2326   //check "if not HandleAllocated" stops the work, when passive file-tabs are
2327   //trying to restore Ed.LineTop.
2328   // https://github.com/Alexey-T/CudaText/issues/3112
2329   //to fix this issue, let's not Exit "if not HandleAllocated",
2330   //but handle this in GetCharSize(), via GetDC(0)
2331 
2332   if not HandleAllocated then
2333     if FWrapMode<>cWrapOff then
2334       exit;
2335 
2336   //must init FRect* if called before first paint (wrapped items need it)
2337   if FRectMain.Width=0 then
2338     UpdateInitialVars(Canvas);
2339 
2340   GlobalCharSizer.Init(Font.Name, DoScaleFont(Font.Size));
2341 
2342   //virtual mode allows faster usage of WrapInfo
2343   CurStrings:= Strings;
2344   FWrapInfo.StringsObj:= CurStrings;
2345   FWrapInfo.VirtualMode:=
2346     (FWrapMode=cWrapOff) and
2347     (Fold.Count=0) and
2348     (CurStrings.Count>2);
2349   if FWrapInfo.VirtualMode then exit;
2350 
2351   bConsiderFolding:= Fold.Count>0;
2352   NNewVisibleColumns:= GetVisibleColumns;
2353   NIndentMaximal:= Max(2, NNewVisibleColumns-cMinCharsAfterAnyIndent); //don't do too big NIndent
2354 
2355   if AForceUpdate then
2356     FWrapUpdateNeeded:= true
2357   else
2358   if (not FWrapUpdateNeeded) and
2359     (FWrapMode<>cWrapOff) and
2360     (FWrapInfo.VisibleColumns<>NNewVisibleColumns) then
2361     FWrapUpdateNeeded:= true;
2362 
2363   if not FWrapUpdateNeeded then Exit;
2364   FWrapUpdateNeeded:= false;
2365   FWrapInfo.VisibleColumns:= NNewVisibleColumns;
2366 
2367   case FWrapMode of
2368     cWrapOff:
2369       FWrapInfo.WrapColumn:= 0;
2370     cWrapOn:
2371       FWrapInfo.WrapColumn:= Max(cMinWrapColumn, NNewVisibleColumns-FWrapAddSpace);
2372     cWrapAtMargin:
2373       FWrapInfo.WrapColumn:= Max(cMinWrapColumn, FMarginRight);
2374     cWrapAtWindowOrMargin:
2375       FWrapInfo.WrapColumn:= Max(cMinWrapColumn, Min(NNewVisibleColumns-FWrapAddSpace, FMarginRight));
2376   end;
2377 
2378   UseCachedUpdate:=
2379     (FWrapInfo.Count>0) and
2380     (CurStrings.Count>cMaxLinesForOldWrapUpdate) and
2381     (not CurStrings.ListUpdatesHard) and
2382     (CurStrings.ListUpdates.Count>0);
2383   //UseCachedUpdate:= false;////to disable
2384 
2385   FWrapTemps.Clear;
2386 
2387   if not UseCachedUpdate then
2388   begin
2389     FWrapInfo.Clear;
2390     FWrapInfo.SetCapacity(CurStrings.Count);
2391     for i:= 0 to CurStrings.Count-1 do
2392     begin
2393       DoCalcWrapInfos(i, NIndentMaximal, FWrapTemps, bConsiderFolding);
2394       for j:= 0 to FWrapTemps.Count-1 do
2395         FWrapInfo.Add(FWrapTemps[j]);
2396     end;
2397     FWrapTemps.Clear;
2398   end
2399   else
2400   begin
2401     //cached WrapInfo update - calculate info only for changed lines (Strings.ListUpdates)
2402     //and insert results into WrapInfo
2403     ListNums:= TATIntegerList.Create;
2404     try
2405       ListNums.Assign(CurStrings.ListUpdates);
2406 
2407       for i:= 0 to ListNums.Count-1 do
2408       begin
2409         NLine:= ListNums[i];
2410         DoCalcWrapInfos(NLine, NIndentMaximal, FWrapTemps, bConsiderFolding);
2411         if FWrapTemps.Count=0 then Continue;
2412 
2413         FWrapInfo.FindIndexesOfLineNumber(NLine, NIndexFrom, NIndexTo);
2414         if NIndexFrom<0 then
2415         begin
2416           //Showmessage('Cant find wrap-index for line '+Inttostr(NLine));
2417           Continue;
2418         end;
2419 
2420         //slow for 100carets, 1M lines, so made method in which
2421         //we can optimize it (instead of del/ins do assign)
2422         FWrapInfo.ReplaceItems(NIndexFrom, NIndexTo, FWrapTemps);
2423       end;
2424       FWrapTemps.Clear;
2425     finally
2426       FreeAndNil(ListNums);
2427     end;
2428   end;
2429 
2430   CurStrings.ListUpdates.Clear;
2431   CurStrings.ListUpdatesHard:= false;
2432 
2433   {$ifdef debug_findwrapindex}
2434   DebugFindWrapIndex;
2435   {$endif}
2436 end;
2437 
2438 
2439 procedure _CalcWrapInfos(
2440   AStrings: TATStrings;
2441   ATabHelper: TATStringTabHelper;
2442   AEditorIndex: integer;
2443   AWrapColumn: integer;
2444   AWrapIndented: boolean;
2445   AVisibleColumns: integer;
2446   const ANonWordChars: atString;
2447   ALineIndex: integer;
2448   AIndentMaximal: integer;
2449   AItems: TATWrapItems;
2450   AConsiderFolding: boolean);
2451 var
2452   WrapItem: TATWrapItem;
2453   NPartOffset, NLen, NIndent, NVisColumns: integer;
2454   NFoldFrom: integer;
2455   FinalState: TATWrapItemFinal;
2456   bInitialItem: boolean;
2457   StrPart: atString;
2458 begin
2459   AItems.Clear;
2460 
2461   //line folded entirely?
2462   if AConsiderFolding then
2463     if AStrings.LinesHidden[ALineIndex, AEditorIndex] then Exit;
2464 
2465   NLen:= AStrings.LinesLen[ALineIndex];
2466 
2467   if NLen=0 then
2468   begin
2469     WrapItem.Init(ALineIndex, 1, 0, 0, cWrapItemFinal, true);
2470     AItems.Add(WrapItem);
2471     Exit;
2472   end;
2473 
2474   //consider fold, before wordwrap
2475   if AConsiderFolding then
2476   begin
2477     //line folded partially?
2478     NFoldFrom:= AStrings.LinesFoldFrom[ALineIndex, AEditorIndex];
2479     if NFoldFrom>0 then
2480     begin
2481       WrapItem.Init(ALineIndex, 1, Min(NLen, NFoldFrom-1), 0, cWrapItemCollapsed, true);
2482       AItems.Add(WrapItem);
2483       Exit;
2484     end;
2485   end;
2486 
2487   //line not wrapped?
2488   if (AWrapColumn<cMinWrapColumnAbs) then
2489   begin
2490     WrapItem.Init(ALineIndex, 1, NLen, 0, cWrapItemFinal, true);
2491     AItems.Add(WrapItem);
2492     Exit;
2493   end;
2494 
2495   NVisColumns:= Max(AVisibleColumns, cMinWrapColumnAbs);
2496   NPartOffset:= 1;
2497   NIndent:= 0;
2498   bInitialItem:= true;
2499 
2500   repeat
2501     StrPart:= AStrings.LineSub(ALineIndex, NPartOffset, NVisColumns);
2502     if StrPart='' then Break;
2503 
2504     NLen:= ATabHelper.FindWordWrapOffset(
2505       ALineIndex,
2506       //very slow to calc for entire line (eg len=70K),
2507       //calc for first NVisColumns chars
2508       StrPart,
2509       Max(AWrapColumn-NIndent, cMinWrapColumnAbs),
2510       ANonWordChars,
2511       AWrapIndented);
2512 
2513     if NLen>=Length(StrPart) then
2514       FinalState:= cWrapItemFinal
2515     else
2516       FinalState:= cWrapItemMiddle;
2517 
2518     WrapItem.Init(ALineIndex, NPartOffset, NLen, NIndent, FinalState, bInitialItem);
2519     AItems.Add(WrapItem);
2520     bInitialItem:= false;
2521 
2522     if AWrapIndented then
2523       if NPartOffset=1 then
2524       begin
2525         NIndent:= ATabHelper.GetIndentExpanded(ALineIndex, StrPart);
2526         NIndent:= Min(NIndent, AIndentMaximal);
2527       end;
2528 
2529     Inc(NPartOffset, NLen);
2530   until false;
2531 end;
2532 
2533 
2534 procedure TATSynEdit.DoCalcWrapInfos(ALine: integer; AIndentMaximal: integer; AItems: TATWrapItems;
2535   AConsiderFolding: boolean);
2536 begin
2537   _CalcWrapInfos(
2538     Strings,
2539     FTabHelper,
2540     FEditorIndex,
2541     FWrapInfo.WrapColumn,
2542     FWrapIndented,
2543     GetVisibleColumns,
2544     FOptNonWordChars,
2545     ALine,
2546     AIndentMaximal,
2547     AItems,
2548     AConsiderFolding);
2549 end;
2550 
2551 
GetVisibleLinesnull2552 function TATSynEdit.GetVisibleLines: integer;
2553 begin
2554   Result:= FRectMainVisible.Height div FCharSize.Y;
2555 end;
2556 
GetVisibleColumnsnull2557 function TATSynEdit.GetVisibleColumns: integer;
2558 begin
2559   Result:= FRectMainVisible.Width * ATEditorCharXScale div FCharSize.XScaled;
2560 end;
2561 
GetVisibleLinesMinimapnull2562 function TATSynEdit.GetVisibleLinesMinimap: integer;
2563 begin
2564   Result:= FRectMinimap.Height div FCharSizeMinimap.Y - 1;
2565 end;
2566 
GetActualProximityVertnull2567 function TATSynEdit.GetActualProximityVert: integer;
2568 begin
2569   Result:= FOptCaretProximityVert;
2570   if Result>0 then
2571     Result:= Min(Min(Result, 10), GetVisibleLines div 2 - 1)
2572 end;
2573 
GetMinimapScrollPosnull2574 function TATSynEdit.GetMinimapScrollPos: integer;
2575 begin
2576   Result:=
2577     Int64(Max(0, FScrollVert.NPos)) *
2578     Max(0, FScrollVert.NMax-GetVisibleLinesMinimap) div
2579     Max(1, FScrollVert.NMax-FScrollVert.NPage);
2580 end;
2581 
2582 procedure TATSynEdit.SetTabSize(AValue: integer);
2583 begin
2584   if FTabSize=AValue then Exit;
2585   FTabSize:= Min(cMaxTabSize, Max(cMinTabSize, AValue));
2586   FWrapUpdateNeeded:= true;
2587   FTabHelper.TabSize:= FTabSize;
2588 end;
2589 
2590 procedure TATSynEdit.SetTabSpaces(AValue: boolean);
2591 begin
2592   if FOptTabSpaces=AValue then Exit;
2593   FOptTabSpaces:= AValue;
2594   FTabHelper.TabSpaces:= AValue;
2595 end;
2596 
2597 procedure TATSynEdit.SetText(const AValue: UnicodeString);
2598 begin
2599   Strings.LoadFromString(UTF8Encode(AValue));
2600 
2601   DoCaretSingle(0, 0);
2602   if Assigned(FMarkers) then
2603     FMarkers.Clear;
2604   if Assigned(FAttribs) then
2605     FAttribs.Clear;
2606   if Assigned(FLinkCache) then
2607     FLinkCache.Clear;
2608 
2609   Update(true);
2610 end;
2611 
2612 procedure TATSynEdit.SetWrapMode(AValue: TATEditorWrapMode);
2613 var
2614   NLine: integer;
2615   Caret: TATCaretItem;
2616 begin
2617   if FWrapMode=AValue then Exit;
2618 
2619   //disable setting wrap=on for too big files
2620   if FWrapMode=cWrapOff then
2621     if Strings.Count>=FWrapEnabledForMaxLines then exit;
2622 
2623   NLine:= LineTop;
2624   FWrapMode:= AValue;
2625 
2626   FWrapUpdateNeeded:= true;
2627   UpdateWrapInfo; //helps to solve https://github.com/Alexey-T/CudaText/issues/2879
2628                   //FWrapUpdateNeeded:=true and Update() is not enough
2629 
2630   if FWrapMode<>cWrapOff then
2631     FScrollHorz.SetZero;
2632 
2633   Update;
2634   LineTop:= NLine;
2635 
2636   //when very long line has caret at end, and we toggle wordwrap, let's scroll to new caret pos
2637   if FWrapMode=cWrapOff then
2638     if Carets.Count=1 then
2639     begin
2640       Caret:= Carets[0];
2641       if Caret.PosX>0 then
2642         DoShowPos(
2643           Point(Caret.PosX, Caret.PosY),
2644           FOptScrollIndentCaretHorz,
2645           FOptScrollIndentCaretVert,
2646           true,
2647           true,
2648           false);
2649       end;
2650 end;
2651 
2652 procedure TATSynEdit.SetWrapIndented(AValue: boolean);
2653 begin
2654   if FWrapIndented=AValue then Exit;
2655   FWrapIndented:=AValue;
2656   if FWrapMode<>cWrapOff then
2657     FWrapUpdateNeeded:= true;
2658 end;
2659 
TATSynEdit.UpdateScrollbarsnull2660 function TATSynEdit.UpdateScrollbars(AdjustSmoothPos: boolean): boolean;
2661 //returns True is scrollbars visibility was changed
2662 var
2663   bVert1, bVert2, bHorz1, bHorz2: boolean;
2664   bVertOur1, bVertOur2, bHorzOur1, bHorzOur2: boolean;
2665   bChangedBarsOs, bChangedBarsOur: boolean;
2666   NPos, NLineIndex, NGapPos, NGapAll: integer;
2667 begin
2668   Result:= false;
2669 
2670   if ModeOneLine then
2671   begin
2672     FScrollbarVert.Hide;
2673     FScrollbarHorz.Hide;
2674     //don't exit, we still need calculation of FScrollHorz fields
2675   end;
2676 
2677   NGapAll:= 0;
2678   NGapPos:= 0;
2679 
2680   //consider Gaps for vertical scrollbar
2681   if Gaps.Count>0 then
2682   begin
2683     if AdjustSmoothPos then
2684     begin
2685       NLineIndex:= 0;
2686       NPos:= Max(0, FScrollVert.NPos);
2687       if FWrapInfo.IsIndexValid(NPos) then
2688         NLineIndex:= FWrapInfo.Data[NPos].NLineIndex;
2689       NGapPos:= Gaps.SizeForLineRange(-1, NLineIndex-1);
2690     end;
2691 
2692     NGapAll:= Gaps.SizeForAll;
2693   end;
2694 
2695   if not ModeOneLine then
2696   with FScrollVert do
2697   begin
2698     NPage:= Max(1, GetVisibleLines)-1;
2699     NMax:= Max(0, FWrapInfo.Count-1); //must be 0 for single line text
2700     if FOptLastLineOnTop then
2701       Inc(NMax, NPage);
2702     NPosLast:= Max(0, NMax-NPage);
2703 
2704     SmoothCharSize:= FCharSize.Y;
2705     SmoothMax:= NMax*SmoothCharSize + NGapAll;
2706     SmoothPage:= NPage*SmoothCharSize;
2707     SmoothPosLast:= Max(0, SmoothMax - SmoothPage);
2708     if AdjustSmoothPos then
2709       SmoothPos:= TotalOffset + NGapPos;
2710   end;
2711 
2712   with FScrollHorz do
2713   begin
2714     NPage:= Max(1, GetVisibleColumns);
2715     //NMax is calculated in DoPaintText
2716     //hide horz bar for word-wrap:
2717     if FWrapMode=cWrapOn then
2718       NMax:= NPage;
2719     NPosLast:= Max(0, NMax-NPage);
2720 
2721     SmoothCharSize:= FCharSize.XScaled div ATEditorCharXScale;
2722     SmoothMax:= NMax*SmoothCharSize;
2723     SmoothPage:= NPage*SmoothCharSize;
2724     SmoothPosLast:= Max(0, SmoothMax - SmoothPage);
2725     if AdjustSmoothPos then
2726       SmoothPos:= TotalOffset;
2727   end;
2728 
2729   //don't need further code for OneLine
2730   if ModeOneLine then exit;
2731 
2732   bVert1:= ShowOsBarVert;
2733   bHorz1:= ShowOsBarHorz;
2734   bVertOur1:= FScrollbarVert.Visible;
2735   bHorzOur1:= FScrollbarHorz.Visible;
2736 
2737   UpdateScrollbarVert;
2738   UpdateScrollbarHorz;
2739 
2740   bVert2:= ShowOsBarVert;
2741   bHorz2:= ShowOsBarHorz;
2742   bVertOur2:= FScrollbarVert.Visible;
2743   bHorzOur2:= FScrollbarHorz.Visible;
2744 
2745   bChangedBarsOs:= (bVert1<>bVert2) or (bHorz1<>bHorz2);
2746   bChangedBarsOur:= (bVertOur1<>bVertOur2) or (bHorzOur1<>bHorzOur2);
2747 
2748   Result:= bChangedBarsOs or bChangedBarsOur;
2749   if Result then
2750     UpdateClientSizes;
2751 
2752   if (FPrevHorz<>FScrollHorz) or
2753     (FPrevVert<>FScrollVert) then
2754   begin
2755     FPrevHorz:= FScrollHorz;
2756     FPrevVert:= FScrollVert;
2757     Include(FPaintFlags, cIntFlagScrolled);
2758   end;
2759 end;
2760 
2761 procedure TATSynEdit.UpdateScrollbarVert;
2762 var
2763   NeedBar: boolean;
2764   si: TScrollInfo;
2765   NDelta: Int64;
2766 begin
2767   case FOptScrollStyleVert of
2768     aessHide:
2769       NeedBar:= false;
2770     aessShow:
2771       NeedBar:= true;
2772     aessAuto:
2773       NeedBar:= (FScrollVert.SmoothPos>0) or (FScrollVert.NMax>FScrollVert.NPage);
2774   end;
2775 
2776   FScrollbarVert.Visible:= NeedBar and FOptScrollbarsNew;
2777   ShowOsBarVert:= NeedBar and not FOptScrollbarsNew;
2778 
2779   if FScrollbarVert.Visible then
2780   begin
2781     FScrollbarLock:= true;
2782 
2783     //if option "minimap on scrollbar" on, scrollbar shows all lines (from 0 to St.Count-1)
2784     //including folded lines.
2785     //if option is off, it shows smaller range, if lines are folded.
2786     if FMicromapOnScrollbar then
2787     begin
2788       if FOptScrollSmooth then
2789         NDelta:= FCharSize.Y
2790       else
2791         NDelta:= 1;
2792       FScrollbarVert.Min:= 0;
2793       FScrollbarVert.Max:= NDelta * Max(0, Strings.Count-1);
2794       FScrollbarVert.SmallChange:= NDelta;
2795       FScrollbarVert.PageSize:= NDelta * Max(1, GetVisibleLines);
2796       FScrollbarVert.Position:= NDelta * LineTop;
2797     end
2798     else
2799     begin
2800       FScrollbarVert.Min:= 0;
2801       FScrollbarVert.Max:= FScrollVert.SmoothMax;
2802       FScrollbarVert.SmallChange:= FScrollVert.SmoothCharSize;
2803       FScrollbarVert.PageSize:= FScrollVert.SmoothPage;
2804       FScrollbarVert.Position:= FScrollVert.SmoothPos;
2805     end;
2806 
2807     FScrollbarVert.Update;
2808     FScrollbarLock:= false;
2809   end;
2810 
2811   if ShowOsBarVert then
2812   begin
2813     FillChar(si{%H-}, SizeOf(si), 0);
2814     si.cbSize:= SizeOf(si);
2815     si.fMask:= SIF_ALL; //or SIF_DISABLENOSCROLL; //todo -- DisableNoScroll doesnt work(Win)
2816     si.nMin:= 0;
2817     si.nMax:= FScrollVert.SmoothMax;
2818     si.nPage:= FScrollVert.SmoothPage;
2819     //if FOptScrollbarsNew then
2820     //  si.nPage:= si.nMax+1;
2821     si.nPos:= FScrollVert.SmoothPos;
2822     SetScrollInfo(Handle, SB_VERT, si, True);
2823   end;
2824 
2825   {$ifdef debug_scroll}
2826   Writeln(Format('ATSynEdit SetScrollInfo: SB_VERT, nMin=%d, nMax=%d, nPage=%d, nPos=%d',
2827     [FScrollVert.NMin, FScrollVert.NMax, FScrollVert.NPage, FScrollVert.NPos]));
2828   {$endif}
2829 end;
2830 
2831 procedure TATSynEdit.UpdateScrollbarHorz;
2832 var
2833   NeedBar: boolean;
2834   si: TScrollInfo;
2835 begin
2836   case FOptScrollStyleHorz of
2837     aessHide:
2838       NeedBar:= false;
2839     aessShow:
2840       NeedBar:= true;
2841     aessAuto:
2842       NeedBar:= (FScrollHorz.SmoothPos>0) or (FScrollHorz.NMax>FScrollHorz.NPage);
2843   end;
2844 
2845   FScrollbarHorz.Visible:= NeedBar and FOptScrollbarsNew;
2846   ShowOsBarHorz:= NeedBar and not FOptScrollbarsNew;
2847 
2848   if FScrollbarHorz.Visible then
2849   begin
2850     FScrollbarLock:= true;
2851     FScrollbarHorz.Min:= 0;
2852     FScrollbarHorz.Max:= FScrollHorz.SmoothMax;
2853     FScrollbarHorz.SmallChange:= FScrollHorz.SmoothCharSize;
2854     FScrollbarHorz.PageSize:= FScrollHorz.SmoothPage;
2855     FScrollbarHorz.Position:= FScrollHorz.SmoothPos;
2856     FScrollbarHorz.Update;
2857     if FScrollbarVert.Visible then
2858       FScrollbarHorz.IndentCorner:= 100
2859     else
2860       FScrollbarHorz.IndentCorner:= 0;
2861     FScrollbarLock:= false;
2862   end;
2863 
2864   if ShowOsBarHorz then
2865   begin
2866     FillChar(si{%H-}, SizeOf(si), 0);
2867     si.cbSize:= SizeOf(si);
2868     si.fMask:= SIF_ALL; //or SIF_DISABLENOSCROLL; don't work
2869     si.nMin:= 0;
2870     si.nMax:= FScrollHorz.SmoothMax;
2871     si.nPage:= FScrollHorz.SmoothPage;
2872     //if FOptScrollbarsNew or FOptScrollbarHorizontalHidden then
2873     //  si.nPage:= si.nMax+1;
2874     si.nPos:= FScrollHorz.SmoothPos;
2875     SetScrollInfo(Handle, SB_HORZ, si, True);
2876   end;
2877 
2878   {$ifdef debug_scroll}
2879   Writeln(Format('ATSynEdit SetScrollInfo: SB_HORZ, nMin=%d, nMax=%d, nPage=%d, nPos=%d',
2880     [FScrollHorz.NMin, FScrollHorz.NMax, FScrollHorz.NPage, FScrollHorz.NPos]));
2881   {$endif}
2882 end;
2883 
2884 procedure TATSynEdit.GetRectMain(out R: TRect);
2885 begin
2886   R.Left:= FRectGutter.Left + FTextOffset.X;
2887   R.Top:= FTextOffset.Y;
2888   R.Right:= ClientWidth
2889     - IfThen(FMinimapVisible and not FMinimapAtLeft, FMinimapWidth)
2890     - IfThen(FMicromapVisible and not FMicromapOnScrollbar, FRectMicromap.Width);
2891   R.Bottom:= ClientHeight;
2892 
2893   FRectMainVisible:= R;
2894 
2895   if FOptScrollSmooth then
2896   begin
2897     Dec(R.Left, FScrollHorz.NPixelOffset);
2898     Dec(R.Top, FScrollVert.NPixelOffset);
2899   end;
2900 end;
2901 
2902 procedure TATSynEdit.GetRectMinimap(out R: TRect);
2903 begin
2904   if not FMinimapVisible then
2905   begin
2906     R:= cRectEmpty;
2907     exit
2908   end;
2909 
2910   if FMinimapAtLeft then
2911     R.Left:= 0
2912   else
2913     R.Left:= ClientWidth-FMinimapWidth-IfThen(FMicromapVisible and not FMicromapOnScrollbar, FRectMicromap.Width);
2914 
2915   R.Right:= R.Left+FMinimapWidth;
2916   R.Top:= 0;
2917   R.Bottom:= ClientHeight;
2918 end;
2919 
2920 procedure TATSynEdit.GetRectMinimapSel(out R: TRect);
2921 begin
2922   R.Left:= FRectMinimap.Left;
2923   R.Right:= FRectMinimap.Right;
2924   R.Top:= GetMinimapSelTop;
2925   R.Bottom:= Min(
2926     R.Top + (GetVisibleLines+1)*FCharSizeMinimap.Y,
2927     FRectMinimap.Bottom
2928     );
2929 end;
2930 
2931 procedure TATSynEdit.GetRectMicromap(out R: TRect);
2932 var
2933   NSize: integer;
2934 begin
2935   NSize:= FMicromap.UpdateSizes(EditorScale(FCharSize.XScaled) div ATEditorCharXScale);
2936 
2937   if not FMicromapVisible or FMicromapOnScrollbar then
2938   begin
2939     R:= cRectEmpty;
2940   end
2941   else
2942   begin
2943     R.Top:= 0;
2944     R.Bottom:= ClientHeight;
2945     R.Right:= ClientWidth;
2946     R.Left:= R.Right-NSize;
2947   end;
2948 
2949   FMicromap.UpdateCoords;
2950   FMicromapScaleDiv:= Max(1, Strings.Count);
2951   if OptLastLineOnTop then
2952     FMicromapScaleDiv:= Max(1, FMicromapScaleDiv+GetVisibleLines-1);
2953 end;
2954 
2955 procedure TATSynEdit.GetRectGutter(out R: TRect);
2956 begin
2957   R.Left:= IfThen(FMinimapVisible and FMinimapAtLeft, FMinimapWidth);
2958   R.Top:= IfThen(FOptRulerVisible, FRulerHeight);
2959   R.Right:= R.Left + FGutter.Width;
2960   R.Bottom:= ClientHeight;
2961 
2962   if not FOptGutterVisible then
2963   begin
2964     R.Right:= R.Left;
2965     R.Bottom:= R.Top;
2966     exit
2967   end;
2968 
2969   Gutter.GutterLeft:= R.Left;
2970   Gutter.Update;
2971 end;
2972 
2973 procedure TATSynEdit.GetRectRuler(out R: TRect);
2974 begin
2975   if not FOptRulerVisible then
2976   begin
2977     R:= cRectEmpty;
2978     exit
2979   end;
2980 
2981   R.Left:= FRectGutter.Left;
2982   R.Right:= FRectMain.Right;
2983   R.Top:= 0;
2984   R.Bottom:= R.Top + FRulerHeight;
2985 end;
2986 
2987 procedure TATSynEdit.UpdateClientSizes;
2988 begin
2989   GetClientSizes(FClientW, FClientH);
2990 end;
2991 
2992 procedure TATSynEdit.UpdateInitialVars(C: TCanvas);
2993 begin
2994   UpdateClientSizes;
2995 
2996   C.Font.Name:= Font.Name;
2997   C.Font.Size:= DoScaleFont(Font.Size);
2998 
2999   FCharSize:= GetCharSize(C, FSpacingY);
3000 
3001   if FSpacingY<0 then
3002     FTextOffsetFromTop:= FSpacingY
3003   else
3004     FTextOffsetFromTop:= 0;
3005   FTextOffsetFromTop1:= FTextOffsetFromTop; //"-1" gives artifacts on gutter bands
3006 
3007   if FMinimapCustomScale<100 then
3008   begin
3009     FCharSizeMinimap.XScaled:= EditorScale(1) * ATEditorCharXScale;
3010     FCharSizeMinimap.Y:= EditorScale(2);
3011   end
3012   else
3013   begin
3014     FCharSizeMinimap.XScaled:= 1 * FMinimapCustomScale div 100 * ATEditorCharXScale;
3015     FCharSizeMinimap.Y:= 2 * FMinimapCustomScale div 100;
3016   end;
3017 
3018   FNumbersIndent:= FCharSize.XScaled * FOptNumbersIndentPercents div 100 div ATEditorCharXScale;
3019   FRulerHeight:= FCharSize.Y * FOptRulerHeightPercents div 100;
3020 
3021   if FOptGutterVisible and FOptNumbersAutosize then
3022     UpdateGutterAutosize;
3023 
3024   FTextOffset:= GetTextOffset; //after gutter autosize
3025 
3026   if FMinimapVisible then
3027     UpdateMinimapAutosize; //after FTextOffset
3028 
3029   GetRectMicromap(FRectMicromap);
3030   GetRectMinimap(FRectMinimap); //after micromap
3031   GetRectGutter(FRectGutter);
3032   GetRectMain(FRectMain); //after gutter/minimap/micromap
3033   GetRectRuler(FRectRuler); //after main
3034 end;
3035 
3036 procedure TATSynEdit.DoPaintMain(C: TCanvas; ALineFrom: integer);
3037 const
3038   cTextMacro = 'R';
3039 begin
3040   C.Brush.Color:= FColorBG;
3041   C.FillRect(0, 0, Width, Height); //avoid FClientW here to fill entire area
3042 
3043   UpdateWrapInfo; //update WrapInfo before MinimapThread start
3044 
3045   if FMinimapVisible then
3046   begin
3047     {$ifdef map_th}
3048     if not Assigned(FMinimapThread) then
3049     begin
3050       FEventMapStart:= TSimpleEvent.Create;
3051       FEventMapDone:= TSimpleEvent.Create;
3052       FMinimapThread:= TATMinimapThread.Create(true);
3053       FMinimapThread.FreeOnTerminate:= false;
3054       FMinimapThread.Editor:= Self;
3055       FMinimapThread.Start;
3056     end;
3057     FEventMapStart.SetEvent;
3058     {$else}
3059     DoPaintMinimapAllToBGRABitmap;
3060     {$endif}
3061   end;
3062 
3063   UpdateLinksAttribs;
3064   DoPaintText(C, FRectMain, FCharSize, FOptGutterVisible, FScrollHorz, FScrollVert, ALineFrom);
3065   DoPaintMargins(C);
3066   DoPaintNiceScroll(C);
3067 
3068   if FOptRulerVisible then
3069   begin
3070     DoPaintRuler(C);
3071     if Assigned(FOnDrawRuler) then
3072       FOnDrawRuler(Self, C, FRectRuler);
3073   end;
3074 
3075   if Assigned(FOnDrawEditor) then
3076     FOnDrawEditor(Self, C, FRectMain);
3077 
3078   if FMicromapVisible and not FMicromapOnScrollbar then
3079     DoPaintMicromap(C);
3080 
3081   if FOptBorderMacroRecording and FIsMacroRecording then
3082   begin
3083     DoPaintBorder(C, Colors.Markers, FOptBorderWidthMacro, true);
3084     C.Brush.Color:= Colors.Markers;
3085     C.Font.Color:= Colors.TextSelFont;
3086     CanvasTextOutSimplest(C,
3087       FRectMain.Right-Length(cTextMacro)*FCharSize.XScaled div ATEditorCharXScale - FOptBorderWidthMacro,
3088       FRectMain.Bottom-FCharSize.Y,
3089       cTextMacro);
3090   end
3091   else
3092   if FOptBorderFocusedActive and FIsEntered and (FOptBorderWidthFocused>0) then
3093     DoPaintBorder(C, Colors.BorderLineFocused, FOptBorderWidthFocused, false)
3094   else
3095   if FOptBorderVisible and (FOptBorderWidth>0) then
3096     DoPaintBorder(C, Colors.BorderLine, FOptBorderWidth, false);
3097 
3098   if FOptShowMouseSelFrame then
3099     if FMouseDragCoord.X>=0 then
3100       DoPaintMouseSelFrame(C);
3101 
3102   if FMinimapVisible then
3103   begin
3104     if FMinimapTooltipVisible and FMinimapTooltipEnabled then
3105       DoPaintMinimapTooltip(C);
3106 
3107     {$ifdef map_th}
3108     if FEventMapDone.WaitFor(1000)=wrSignaled then
3109     begin
3110       FEventMapDone.ResetEvent;
3111       FMinimapBmp.Draw(C, FRectMinimap.Left, FRectMinimap.Top);
3112     end;
3113     {$else}
3114     FMinimapBmp.Draw(C, FRectMinimap.Left, FRectMinimap.Top);
3115     {$endif}
3116   end;
3117 end;
3118 
3119 procedure TATSynEdit.DoPaintMouseSelFrame(C: TCanvas);
3120 const
3121   cMinSize = 4; //minimal width/height of the frame in pixels
3122 var
3123   X1, X2, Y1, Y2: integer;
3124   XX1, XX2, YY1, YY2: integer;
3125 begin
3126   if not FOptMouseEnableNormalSelection then exit;
3127 
3128   if FMouseDownCoord.Y<0 then exit;
3129 
3130   X1:= FMouseDownCoord.X - FScrollHorz.TotalOffset;
3131   X2:= FMouseDragCoord.X;
3132   Y1:= FMouseDownCoord.Y - FScrollVert.TotalOffset;
3133   Y2:= FMouseDragCoord.Y;
3134 
3135   XX1:= Max(-1, Min(X1, X2));
3136   YY1:= Max(-1, Min(Y1, Y2));
3137   XX2:= Min(Width+1, Max(X1, X2));
3138   YY2:= Min(Height+1, Max(Y1, Y2));
3139 
3140   if XX1<0 then exit;
3141   if XX2-XX1<cMinSize then exit;
3142   if YY2-YY1<cMinSize then exit;
3143 
3144   //avoid TCanvas.DrawFocusRect(), sometimes it's painted bad on Qt5
3145   C.Pen.Color:= ColorBlendHalf(Colors.TextFont, Colors.TextBG);
3146   CanvasLineHorz(C, XX1, YY1, XX2, true);
3147   CanvasLineHorz(C, XX1, YY2, XX2, true);
3148   CanvasLineVert(C, XX1, YY1, YY2, true);
3149   CanvasLineVert(C, XX2, YY1, YY2, true);
3150 end;
3151 
3152 procedure TATSynEdit.DoPaintBorder(C: TCanvas; AColor: TColor;
3153   ABorderWidth: integer; AUseRectMain: boolean);
3154 var
3155   NColorBG, NColorFore: TColor;
3156   W, H, i: integer;
3157 begin
3158   if ABorderWidth<1 then exit;
3159   C.Pen.Color:= AColor;
3160 
3161   if AUseRectMain then
3162   begin
3163     W:= FRectMain.Right;
3164     H:= FRectMain.Bottom;
3165   end
3166   else
3167   begin
3168     W:= ClientWidth;
3169     H:= ClientHeight;
3170   end;
3171 
3172   for i:= 0 to ABorderWidth-1 do
3173     C.Frame(i, i, W-i, H-i);
3174 
3175   if FOptBorderVisible and FOptBorderRounded and (ABorderWidth=1) then
3176   begin
3177     NColorBG:= ColorToRGB(Colors.BorderParentBG);
3178     NColorFore:= ColorToRGB(Colors.TextBG);
3179 
3180     CanvasPaintRoundedCorners(C,
3181       Rect(0, 0, W, H),
3182       [acckLeftTop, acckLeftBottom],
3183       NColorBG, AColor, NColorFore);
3184 
3185     if ModeOneLine and FMicromapVisible then
3186       NColorFore:= Colors.ComboboxArrowBG;
3187 
3188     CanvasPaintRoundedCorners(C,
3189       Rect(0, 0, W, H),
3190       [acckRightTop, acckRightBottom],
3191       NColorBG, AColor, NColorFore);
3192   end;
3193 end;
3194 
TATSynEdit.GetCharSizenull3195 function TATSynEdit.GetCharSize(C: TCanvas; ACharSpacingY: integer): TATEditorCharSize;
3196 const
3197   SampleChar = 'N';
3198 var
3199   SampleStrLen: integer;
3200   SampleStr: string;
3201   Size: TSize;
3202   TempC: TCanvas;
3203   dc: HDC;
3204 begin
3205   if ATEditorOptions.PreciseCalculationOfCharWidth then
3206     SampleStrLen:= 128
3207   else
3208     SampleStrLen:= 1;
3209 
3210   SampleStr:= StringOfChar(SampleChar, SampleStrLen);
3211 
3212   if C.HandleAllocated then
3213   begin
3214     Size:= C.TextExtent(SampleStr);
3215   end
3216   else
3217   begin
3218     TempC:= TCanvas.Create;
3219     try
3220       dc:= GetDC(0);
3221       TempC.Handle:= dc;
3222       TempC.Font.Name:= Self.Font.Name;
3223       TempC.Font.Size:= DoScaleFont(Self.Font.Size);
3224       Size:= TempC.TextExtent(SampleStr);
3225       ReleaseDC(dc, 0);
3226     finally
3227       FreeAndNil(TempC);
3228     end;
3229   end;
3230 
3231   Result.XScaled:= Max(1, Size.cx) * ATEditorCharXScale div SampleStrLen;
3232   Result.Y:= Max(1, Size.cy + ACharSpacingY);
3233 end;
3234 
3235 procedure TATSynEdit.DoPaintGutterBandBG(C: TCanvas; AColor: TColor;
3236   AX1, AY1, AX2, AY2: integer; AEntireHeight: boolean);
3237 begin
3238   if not AEntireHeight then
3239   begin
3240     C.Brush.Color:= AColor;
3241     C.FillRect(AX1, AY1, AX2, AY2);
3242   end
3243   else
3244   begin
3245     C.Brush.Color:= AColor;
3246     C.FillRect(AX1, FRectGutter.Top, AX2, FRectGutter.Bottom);
3247   end;
3248 end;
3249 
3250 {
3251 type
3252   PATEditorPaintingItemProp = ^TATEditorPaintingItemProp;
3253   TATEditorPaintingItemProp = record
3254     LineRect: TRect;
3255     WrapIndex: integer;
3256   end;
3257 }
3258 
3259 procedure TATSynEdit.DoPaintText(C: TCanvas;
3260   const ARect: TRect;
3261   const ACharSize: TATEditorCharSize;
3262   AWithGutter: boolean;
3263   var AScrollHorz, AScrollVert: TATEditorScrollInfo;
3264   ALineFrom: integer);
3265 var
3266   RectLine: TRect;
3267   GapItem: TATGapItem;
3268   GutterItem: TATGutterItem;
3269   NWrapIndex, NWrapIndexDummy, NLineCount: integer;
3270 begin
3271   //wrap turned off can cause bad scrollpos, fix it
3272   with AScrollVert do
3273     NPos:= Min(NPos, NPosLast);
3274 
3275   C.Brush.Color:= FColorBG;
3276   C.FillRect(ARect);
3277 
3278   if Assigned(FFoldedMarkList) then
3279     FFoldedMarkList.Clear;
3280 
3281   if AWithGutter then
3282   begin
3283     FColorOfStates[cLineStateNone]:= -1;
3284     FColorOfStates[cLineStateChanged]:= Colors.StateChanged;
3285     FColorOfStates[cLineStateAdded]:= Colors.StateAdded;
3286     FColorOfStates[cLineStateSaved]:= Colors.StateSaved;
3287 
3288     C.Brush.Color:= Colors.GutterBG;
3289     C.FillRect(FRectGutter);
3290 
3291     //paint some bands, for full height coloring
3292     GutterItem:= FGutter[FGutterBandFolding];
3293     if GutterItem.Visible then
3294       DoPaintGutterBandBG(C,
3295         Colors.GutterFoldBG,
3296         GutterItem.Left,
3297         -1,
3298         GutterItem.Right,
3299         -1,
3300         true);
3301 
3302     GutterItem:= FGutter[FGutterBandSeparator];
3303     if GutterItem.Visible then
3304       DoPaintGutterBandBG(C,
3305         Colors.GutterSeparatorBG,
3306         GutterItem.Left,
3307         -1,
3308         GutterItem.Right,
3309         -1,
3310         true);
3311 
3312     GutterItem:= FGutter[FGutterBandEmpty];
3313     if GutterItem.Visible then
3314       DoPaintGutterBandBG(C,
3315         FColorBG,
3316         GutterItem.Left,
3317         -1,
3318         GutterItem.Right,
3319         -1,
3320         true);
3321   end;
3322 
3323   if (FTextHint<>'') then
3324   begin
3325     NLineCount:= Strings.Count;
3326     if (NLineCount=0) or ((NLineCount=1) and (Strings.LinesLen[0]=0)) then
3327     begin
3328       DoPaintTextHintTo(C);
3329       Exit
3330     end;
3331   end;
3332 
3333   {$ifndef fix_horzscroll}
3334   AScrollHorz.NMax:= 1;
3335   {$endif}
3336 
3337   if ALineFrom>=0 then
3338   begin
3339     FWrapInfo.FindIndexesOfLineNumber(ALineFrom, NWrapIndex, NWrapIndexDummy);
3340     DoScroll_SetPos(AScrollVert, NWrapIndex);
3341       //last param True, to continue scrolling after resize
3342   end
3343   else
3344   begin
3345     NWrapIndex:= Max(0, AScrollVert.NPos);
3346   end;
3347 
3348   if FFoldCacheEnabled then
3349     InitFoldbarCache(NWrapIndex);
3350 
3351   DoEventBeforeCalcHilite;
3352 
3353   RectLine.Left:= ARect.Left;
3354   RectLine.Right:= ARect.Right;
3355   RectLine.Top:= 0;
3356   RectLine.Bottom:= ARect.Top;
3357 
3358   repeat
3359     RectLine.Top:= RectLine.Bottom;
3360     RectLine.Bottom:= RectLine.Top+ACharSize.Y;
3361     if RectLine.Top>ARect.Bottom then Break;
3362 
3363     if not FWrapInfo.IsIndexValid(NWrapIndex) then
3364     begin
3365       //paint end-of-file arrow
3366       if NWrapIndex>=0 then
3367         if OptUnprintedVisible and OptUnprintedEof then
3368           if OptUnprintedEndsDetails then
3369             DoPaintUnprintedSymbols(C,
3370               cEndingTextEOF,
3371               ARect.Left,
3372               RectLine.Top,
3373               ACharSize,
3374               Colors.UnprintedFont,
3375               Colors.UnprintedBG)
3376           else
3377             CanvasArrowHorz(C,
3378               RectLine,
3379               Colors.UnprintedFont,
3380               ATEditorOptions.UnprintedEofCharLength*ACharSize.XScaled div ATEditorCharXScale,
3381               false,
3382               ATEditorOptions.UnprintedTabPointerScale);
3383       Break;
3384     end;
3385 
3386     //consider gap before 1st line
3387     if (NWrapIndex=0) and AScrollVert.TopGapVisible and (Gaps.SizeOfGapTop>0) then
3388     begin
3389       GapItem:= Gaps.Find(-1);
3390       if Assigned(GapItem) then
3391         Inc(RectLine.Bottom, GapItem.Size);
3392     end;
3393 
3394     //conside gap for this line
3395     if WrapInfo[NWrapIndex].NFinal=cWrapItemFinal then
3396     begin
3397       GapItem:= Gaps.Find(WrapInfo[NWrapIndex].NLineIndex);
3398       if Assigned(GapItem) then
3399         Inc(RectLine.Bottom, GapItem.Size);
3400     end;
3401 
3402     DoPaintLine(C, RectLine, ACharSize, AScrollHorz, AScrollVert, NWrapIndex, FParts);
3403     if AWithGutter then
3404       DoPaintGutterOfLine(C, RectLine, ACharSize, NWrapIndex);
3405 
3406     //update LineBottom as index of last painted line
3407     FLineBottom:= FWrapInfo[NWrapIndex].NLineIndex;
3408 
3409     Inc(NWrapIndex);
3410   until false;
3411 
3412   //block staples
3413   DoPaintStaples(C, ARect, ACharSize, AScrollHorz);
3414 end;
3415 
3416 procedure TATSynEdit.DoPaintMinimapTextToBGRABitmap(
3417   const ARect: TRect; ACharSize: TATEditorCharSize;
3418   var AScrollHorz, AScrollVert: TATEditorScrollInfo);
3419 var
3420   RectLine: TRect;
3421   NWrapIndex: integer;
3422 begin
3423   FMinimapBmp.SetSize(ARect.Width, ARect.Height);
3424   FMinimapBmp.Fill(FColorBG);
3425 
3426   //wrap turned off can cause bad scrollpos, fix it
3427   with AScrollVert do
3428     NPos:= Min(NPos, NPosLast);
3429 
3430   NWrapIndex:= Max(0, AScrollVert.NPos);
3431 
3432   RectLine.Left:= ARect.Left;
3433   RectLine.Right:= ARect.Right;
3434   RectLine.Top:= 0;
3435   RectLine.Bottom:= ARect.Top;
3436 
3437   repeat
3438     RectLine.Top:= RectLine.Bottom;
3439     RectLine.Bottom:= RectLine.Top+ACharSize.Y;
3440     if RectLine.Top>ARect.Bottom then Break;
3441 
3442     if not FWrapInfo.IsIndexValid(NWrapIndex) then
3443       Break;
3444 
3445     DoPaintMinimapLine(RectLine, ACharSize, AScrollHorz, AScrollVert, NWrapIndex, FPartsMinimap);
3446 
3447     Inc(NWrapIndex);
3448   until false;
3449 end;
3450 
3451 
3452 procedure TATSynEdit.DoPaintLine(C: TCanvas;
3453   ARectLine: TRect;
3454   ACharSize: TATEditorCharSize;
3455   var AScrollHorz, AScrollVert: TATEditorScrollInfo;
3456   const AWrapIndex: integer;
3457   var ATempParts: TATLineParts);
3458   //
3459   procedure FillOneLine(AFillColor: TColor; ARectLeft: integer);
3460   var
3461     R: TRect;
3462   begin
3463     C.Brush.Style:= bsSolid;
3464     C.Brush.Color:= AFillColor;
3465     R:= ARectLine;
3466     //R.Left:= ARectLeft;
3467     Inc(R.Top, FTextOffsetFromTop1);
3468     Inc(R.Bottom, FTextOffsetFromTop1);
3469     C.FillRect(R);
3470   end;
3471   //
3472 var
3473   St: TATStrings;
3474   NLinesIndex, NLineLen, NCount: integer;
3475   NOutputCharsSkipped: Int64;
3476   NOutputStrWidth, NOutputMaximalChars: Int64;
3477   NOutputCellPercentsSkipped: Int64;
3478   NCoordSep: Int64;
3479   WrapItem: TATWrapItem;
3480   GapItem: TATGapItem;
3481   StringItem: PATStringItem;
3482   NColorEntire, NColorAfter: TColor;
3483   NDimValue: integer;
3484   StrOutput: atString;
3485   CurrPoint, CurrPointText, CoordAfterText: TPoint;
3486   LineSeparator: TATLineSeparator;
3487   bLineWithCaret, bLineEolSelected, bLineColorForced, bLineHuge: boolean;
3488   Event: TATSynEditDrawLineEvent;
3489   TextOutProps: TATCanvasTextOutProps;
3490   NSubPos, NSubLen: integer;
3491   bHiliteLinesWithSelection: boolean;
3492   bTrimmedNonSpaces: boolean;
3493   bUseColorOfCurrentLine: boolean;
3494 begin
3495   St:= Strings;
3496   bHiliteLinesWithSelection:= false;
3497 
3498   WrapItem:= FWrapInfo[AWrapIndex];
3499   NLinesIndex:= WrapItem.NLineIndex;
3500   if not St.IsIndexValid(NLinesIndex) then Exit;
3501 
3502   //support Gap before the 1st line
3503   if (AWrapIndex=0) and AScrollVert.TopGapVisible and (Gaps.SizeOfGapTop>0) then
3504   begin
3505     GapItem:= Gaps.Find(-1);
3506     if Assigned(GapItem) then
3507     begin
3508       DoPaintGap(C, Rect(ARectLine.Left, ARectLine.Top, ARectLine.Right, ARectLine.Top+GapItem.Size), GapItem);
3509       Inc(ARectLine.Top, GapItem.Size);
3510     end;
3511   end;
3512 
3513   if IsFoldLineNeededBeforeWrapitem(AWrapIndex) then
3514   begin
3515     NCoordSep:= ARectLine.Top-1;
3516     C.Pen.Color:= Colors.CollapseLine;
3517     CanvasLineHorz(C,
3518       ARectLine.Left+FFoldUnderlineOffset,
3519       NCoordSep,
3520       ARectLine.Right-FFoldUnderlineOffset
3521       );
3522   end;
3523 
3524   //prepare line
3525   NOutputCharsSkipped:= 0;
3526   NOutputCellPercentsSkipped:= 0;
3527   NOutputStrWidth:= 0;
3528 
3529   CurrPoint.X:= ARectLine.Left;
3530   CurrPoint.Y:= ARectLine.Top;
3531   CurrPointText.X:= Int64(CurrPoint.X)
3532                     + Int64(WrapItem.NIndent)*ACharSize.XScaled div ATEditorCharXScale
3533                     - AScrollHorz.SmoothPos
3534                     + AScrollHorz.NPixelOffset;
3535   CurrPointText.Y:= CurrPoint.Y;
3536   Inc(CurrPointText.Y, FTextOffsetFromTop1);
3537 
3538   bTrimmedNonSpaces:= false;
3539 
3540   NLineLen:= St.LinesLen[NLinesIndex];
3541   bLineHuge:= WrapItem.NLength>ATEditorOptions.MaxLineLenForAccurateCharWidths;
3542           //not this: NLineLen>OptMaxLineLenForAccurateCharWidths;
3543 
3544   if not bLineHuge then
3545   begin
3546     //little slow for huge lines
3547     NSubPos:= WrapItem.NCharIndex;
3548     NSubLen:= Min(WrapItem.NLength, FVisibleColumns+AScrollHorz.NPos+1+6);
3549       //+1 because of NPixelOffset
3550       //+6 because of HTML color underlines
3551     StrOutput:= St.LineSub(NLinesIndex, NSubPos, NSubLen);
3552 
3553     if FUnprintedSpacesTrailing then
3554       bTrimmedNonSpaces:= NSubPos+NSubLen <= St.LineLenWithoutSpace(NLinesIndex);
3555 
3556     if WrapItem.bInitial then
3557     begin
3558       //very slow for huge lines
3559       FTabHelper.FindOutputSkipOffset(
3560         NLinesIndex,
3561         StrOutput,
3562         AScrollHorz.NPos,
3563         NOutputCharsSkipped,
3564         NOutputCellPercentsSkipped);
3565       Delete(StrOutput, 1, NOutputCharsSkipped);
3566     end;
3567   end
3568   else
3569   begin
3570     //work faster for huge lines (but not accurate horiz scrollbar)
3571     NOutputCharsSkipped:= AScrollHorz.NPos;
3572     NOutputCellPercentsSkipped:= NOutputCharsSkipped*100;
3573 
3574     NSubPos:= WrapItem.NCharIndex + NOutputCharsSkipped;
3575     NSubLen:= Min(WrapItem.NLength, FVisibleColumns+AScrollHorz.NPos+1+6);
3576       //+1 because of NPixelOffset
3577       //+6 because of HTML color underlines
3578     StrOutput:= St.LineSub(NLinesIndex, NSubPos, NSubLen);
3579 
3580     if FUnprintedSpacesTrailing then
3581       bTrimmedNonSpaces:= NSubPos+NSubLen <= St.LineLenWithoutSpace(NLinesIndex);
3582   end;
3583 
3584   Inc(CurrPointText.X, NOutputCellPercentsSkipped * ACharSize.XScaled div ATEditorCharXScale div 100);
3585 
3586   if Length(StrOutput)>cMaxCharsForOutput then
3587     SetLength(StrOutput, cMaxCharsForOutput);
3588 
3589   if FOptMaskCharUsed then
3590     StrOutput:= StringOfCharW(FOptMaskChar, Length(StrOutput));
3591 
3592   LineSeparator:= St.LinesSeparator[NLinesIndex];
3593   bLineWithCaret:= IsLineWithCaret(NLinesIndex, FOptShowCurLineIfWithoutSel);
3594   bLineEolSelected:= IsPosSelected(WrapItem.NCharIndex-1+WrapItem.NLength, WrapItem.NLineIndex);
3595 
3596   //horz scrollbar max: is calculated here, to make variable horz bar
3597   //vert scrollbar max: is calculated in UpdateScrollbars
3598   if bLineHuge then
3599     NOutputMaximalChars:= NLineLen //approximate, it don't consider CJK chars, but OK for huge lines
3600   else
3601   begin
3602     StringItem:= St.GetItemPtr(NLinesIndex);
3603     if StringItem^.HasAsciiNoTabs then
3604       NOutputMaximalChars:= StringItem^.CharLen
3605     else
3606       NOutputMaximalChars:= CanvasTextWidth(
3607         StringItem^.Line,
3608         NLinesIndex,
3609         FTabHelper,
3610         1 //pass CharWidth=1px
3611         );
3612   end;
3613   AScrollHorz.NMax:= Max(AScrollHorz.NMax, NOutputMaximalChars + FOptScrollbarHorizontalAddSpace);
3614 
3615   C.Brush.Color:= FColorBG;
3616   C.Font.Name:= Font.Name;
3617   C.Font.Size:= DoScaleFont(Font.Size);
3618   C.Font.Color:= FColorFont;
3619 
3620   bUseColorOfCurrentLine:= false;
3621   if bLineWithCaret then
3622     if FOptShowCurLine and (not FOptShowCurLineOnlyFocused or FIsEntered) then
3623     begin
3624       if FOptShowCurLineMinimal then
3625         bUseColorOfCurrentLine:= IsWrapItemWithCaret(WrapItem)
3626       else
3627         bUseColorOfCurrentLine:= true;
3628     end;
3629 
3630   DoCalcLineEntireColor(
3631     NLinesIndex,
3632     bUseColorOfCurrentLine,
3633     NColorEntire,
3634     bLineColorForced,
3635     bHiliteLinesWithSelection);
3636 
3637   if FOptZebraActive then
3638     if (NLinesIndex+1) mod FOptZebraStep = 0 then
3639       NColorEntire:= ColorBlend(NColorEntire, FColorFont, FOptZebraAlphaBlend);
3640 
3641   FillOneLine(NColorEntire, ARectLine.Left);
3642 
3643   //paint line
3644   if StrOutput<>'' then
3645   begin
3646     if (WrapItem.NIndent>0) then
3647     begin
3648       NColorAfter:= FColorBG;
3649       DoCalcPosColor(WrapItem.NCharIndex, NLinesIndex, NColorAfter);
3650       DoPaintLineIndent(C, ARectLine, ACharSize,
3651         ARectLine.Top, WrapItem.NIndent,
3652         NColorAfter,
3653         AScrollHorz.NPos, FOptShowIndentLines);
3654     end;
3655 
3656     NColorAfter:= clNone;
3657 
3658     DoCalcLineHilite(
3659       WrapItem,
3660       ATempParts{%H-},
3661       NOutputCharsSkipped, cMaxCharsForOutput,
3662       NColorEntire, bLineColorForced,
3663       NColorAfter, true);
3664 
3665     if ATempParts[0].Offset<0 then
3666     begin
3667       //some bug in making parts! to fix!
3668       //raise Exception.Create('Program bug in text renderer, report to author!');
3669       C.Font.Color:= clRed;
3670       C.TextOut(CurrPointText.X, CurrPointText.Y, 'Program bug in text renderer, report to author!');
3671       Exit;
3672     end;
3673 
3674     //apply DimRanges
3675     if Assigned(FDimRanges) then
3676     begin
3677       NDimValue:= FDimRanges.GetDimValue(WrapItem.NLineIndex, -1);
3678       if NDimValue>0 then //-1: no ranges found, 0: no effect
3679         DoPartsDim(ATempParts, NDimValue, FColorBG);
3680     end;
3681 
3682     //adapter may return ColorAfterEol, paint it
3683     if FOptShowFullHilite then
3684       if NColorAfter<>clNone then
3685         FillOneLine(NColorAfter, CurrPointText.X);
3686 
3687     Event:= FOnDrawLine;
3688 
3689     if ATEditorOptions.UnprintedReplaceSpec then
3690       SRemoveAsciiControlChars(StrOutput, WideChar(ATEditorOptions.UnprintedReplaceSpecToCode));
3691 
3692     //truncate text to not paint over screen
3693     NCount:= ARectLine.Width * ATEditorCharXScale div ACharSize.XScaled + 2;
3694     if Length(StrOutput)>NCount then
3695       SetLength(StrOutput, NCount);
3696 
3697       TextOutProps.Editor:= Self;
3698       TextOutProps.HasAsciiNoTabs:= St.LinesHasAsciiNoTabs[NLinesIndex];
3699       TextOutProps.SuperFast:= bLineHuge;
3700       TextOutProps.TabHelper:= FTabHelper;
3701       TextOutProps.LineIndex:= NLinesIndex;
3702       TextOutProps.CharIndexInLine:= WrapItem.NCharIndex;
3703       TextOutProps.CharSize:= ACharSize;
3704       TextOutProps.CharsSkipped:= NOutputCellPercentsSkipped div 100;
3705       TextOutProps.TrimmedTrailingNonSpaces:= bTrimmedNonSpaces;
3706       TextOutProps.DrawEvent:= Event;
3707       TextOutProps.ControlWidth:= ClientWidth+ACharSize.XScaled div ATEditorCharXScale * 2;
3708       TextOutProps.TextOffsetFromLine:= FTextOffsetFromTop;
3709 
3710       TextOutProps.ShowUnprinted:= FUnprintedVisible and FUnprintedSpaces;
3711       TextOutProps.ShowUnprintedSpacesTrailing:= FUnprintedSpacesTrailing;
3712       TextOutProps.ShowUnprintedSpacesBothEnds:= FUnprintedSpacesBothEnds;
3713       TextOutProps.ShowUnprintedSpacesOnlyInSelection:= FUnprintedSpacesOnlyInSelection;
3714       TextOutProps.DetectIsPosSelected:= @IsPosSelected;
3715 
3716       TextOutProps.ShowFontLigatures:= FOptShowFontLigatures and (not bLineWithCaret);
3717       TextOutProps.ColorNormalFont:= Colors.TextFont;
3718       TextOutProps.ColorUnprintedFont:= Colors.UnprintedFont;
3719       TextOutProps.ColorUnprintedHexFont:= Colors.UnprintedHexFont;
3720 
3721       TextOutProps.FontNormal_Name:= Font.Name;
3722       TextOutProps.FontNormal_Size:= DoScaleFont(Font.Size);
3723 
3724       TextOutProps.FontItalic_Name:= FontItalic.Name;
3725       TextOutProps.FontItalic_Size:= DoScaleFont(FontItalic.Size);
3726 
3727       TextOutProps.FontBold_Name:= FontBold.Name;
3728       TextOutProps.FontBold_Size:= DoScaleFont(FontBold.Size);
3729 
3730       TextOutProps.FontBoldItalic_Name:= FontBoldItalic.Name;
3731       TextOutProps.FontBoldItalic_Size:= DoScaleFont(FontBoldItalic.Size);
3732 
3733       CanvasTextOut(C,
3734         CurrPointText.X,
3735         CurrPointText.Y,
3736         StrOutput,
3737         @ATempParts,
3738         NOutputStrWidth,
3739         TextOutProps
3740         );
3741 
3742       //paint selection bg, after applying ColorAfterEol
3743       DoPaintSelectedLineBG(C, ACharSize, ARectLine,
3744         CurrPoint,
3745         CurrPointText,
3746         WrapItem,
3747         NOutputStrWidth,
3748         AScrollHorz);
3749 
3750     //restore after textout
3751     C.Font.Style:= Font.Style;
3752   end
3753   else
3754   //paint empty line bg
3755   begin
3756     if FOptShowFullHilite then
3757     begin
3758       NColorAfter:= clNone;
3759       //visible StrOutput is empty, but the line itself may be not empty (because of horz scroll)
3760       DoCalcPosColor(NLineLen, NLinesIndex, NColorAfter);
3761       if NColorAfter<>clNone then
3762         FillOneLine(NColorAfter, ARectLine.Left);
3763     end;
3764 
3765     DoPaintSelectedLineBG(C, ACharSize, ARectLine,
3766       CurrPoint,
3767       CurrPointText,
3768       WrapItem,
3769       0,
3770       AScrollHorz);
3771   end;
3772 
3773   CoordAfterText.X:= CurrPointText.X+NOutputStrWidth;
3774   CoordAfterText.Y:= CurrPointText.Y;
3775 
3776   if WrapItem.NFinal=cWrapItemFinal then
3777   begin
3778     //for OptShowFullWidthForSelection=false paint eol bg
3779     if bLineEolSelected then
3780     begin
3781       C.Brush.Color:= Colors.TextSelBG;
3782       C.FillRect(
3783         CoordAfterText.X,
3784         CoordAfterText.Y,
3785         CoordAfterText.X+ACharSize.XScaled div ATEditorCharXScale,
3786         CoordAfterText.Y+ACharSize.Y);
3787     end;
3788 
3789     //paint eol mark
3790     if FUnprintedVisible and FUnprintedEnds then
3791     begin
3792       if OptUnprintedEndsDetails then
3793         DoPaintUnprintedSymbols(C,
3794           cLineEndsToSymbols[St.LinesEnds[WrapItem.NLineIndex]],
3795           CoordAfterText.X,
3796           CoordAfterText.Y,
3797           ACharSize,
3798           Colors.UnprintedFont,
3799           Colors.UnprintedBG)
3800       else
3801         DoPaintUnprintedEndSymbol(C,
3802           CoordAfterText.X,
3803           CoordAfterText.Y,
3804           ACharSize,
3805           Colors.UnprintedFont,
3806           Colors.TextBG);
3807     end;
3808   end
3809   else
3810   begin
3811     //paint wrapped-line-part mark
3812     if FUnprintedVisible and FUnprintedEnds then
3813       DoPaintUnprintedWrapMark(C,
3814         CoordAfterText.X,
3815         CoordAfterText.Y,
3816         ACharSize,
3817         Colors.UnprintedFont);
3818   end;
3819 
3820   //draw collapsed-mark
3821   if WrapItem.NFinal=cWrapItemCollapsed then
3822     DoPaintFoldedMark(C,
3823       St.LinesFoldFrom[NLinesIndex, FEditorIndex]-1,
3824       NLinesIndex,
3825       CoordAfterText.X,
3826       CoordAfterText.Y,
3827       GetFoldedMarkText(NLinesIndex));
3828 
3829   //draw separators
3830   if (LineSeparator<>cLineSepNone) then
3831   begin
3832     if LineSeparator=cLineSepTop then
3833       NCoordSep:= ARectLine.Top
3834     else
3835       NCoordSep:= ARectLine.Top+ACharSize.Y-1;
3836     C.Pen.Color:= Colors.BlockSepLine;
3837     CanvasLineHorz(C, ARectLine.Left, NCoordSep, ARectLine.Right);
3838   end;
3839 
3840   //consider gap (not for minimap)
3841   if (WrapItem.NFinal=cWrapItemFinal) then
3842   begin
3843     //end of painting line
3844     Inc(ARectLine.Top, ACharSize.Y);
3845 
3846     GapItem:= Gaps.Find(NLinesIndex);
3847     if Assigned(GapItem) then
3848     begin
3849       DoPaintGap(C, Rect(ARectLine.Left, ARectLine.Top, ARectLine.Right, ARectLine.Top+GapItem.Size), GapItem);
3850       Inc(ARectLine.Top, GapItem.Size);
3851     end;
3852   end;
3853 end;
3854 
3855 procedure TATSynEdit.DoPaintMinimapLine(
3856   ARectLine: TRect;
3857   ACharSize: TATEditorCharSize;
3858   var AScrollHorz, AScrollVert: TATEditorScrollInfo;
3859   const AWrapIndex: integer;
3860   var ATempParts: TATLineParts);
3861   //
3862   procedure FillOneLine(AFillColor: TColor; ARectLeft: integer);
3863   begin
3864     FMinimapBmp.FillRect(
3865       ARectLeft - FRectMinimap.Left,
3866       ARectLine.Top - FRectMinimap.Top,
3867       FRectMinimap.Width,
3868       ARectLine.Top - FRectMinimap.Top + ACharSize.Y,
3869       AFillColor);
3870   end;
3871   //
3872 var
3873   St: TATStrings;
3874   NLinesIndex, NCount: integer;
3875   NOutputCharsSkipped: integer;
3876   WrapItem: TATWrapItem;
3877   NColorEntire, NColorAfter: TColor;
3878   StrOutput: atString;
3879   CurrPoint, CurrPointText: TPoint;
3880   bLineColorForced: boolean;
3881   bUseSetPixel: boolean;
3882   bUseColorOfCurrentLine: boolean;
3883 begin
3884   St:= Strings;
3885   bUseSetPixel:=
3886     {$ifndef windows} DoubleBuffered and {$endif}
3887     (ACharSize.XScaled div ATEditorCharXScale = 1);
3888 
3889   if not FWrapInfo.IsIndexValid(AWrapIndex) then Exit; //e.g. main thread updated WrapInfo
3890   WrapItem:= FWrapInfo[AWrapIndex];
3891   NLinesIndex:= WrapItem.NLineIndex;
3892   if not St.IsIndexValid(NLinesIndex) then Exit;
3893 
3894   //prepare line
3895   NOutputCharsSkipped:= 0;
3896 
3897   CurrPoint.X:= ARectLine.Left;
3898   CurrPoint.Y:= ARectLine.Top;
3899   CurrPointText.X:= Int64(CurrPoint.X)
3900                     + Int64(WrapItem.NIndent)*ACharSize.XScaled div ATEditorCharXScale
3901                     - AScrollHorz.SmoothPos
3902                     + AScrollHorz.NPixelOffset;
3903   CurrPointText.Y:= CurrPoint.Y;
3904 
3905   //work very fast for minimap, take LineSub from start
3906   StrOutput:= St.LineSub(
3907     NLinesIndex,
3908     1,
3909     Min(WrapItem.NLength, FVisibleColumns)
3910     );
3911 
3912   //FMinimapBmp.Canvas.Brush.Color:= FColorBG;
3913 
3914   bUseColorOfCurrentLine:= false;
3915 
3916   DoCalcLineEntireColor(
3917     NLinesIndex,
3918     bUseColorOfCurrentLine,
3919     NColorEntire,
3920     bLineColorForced,
3921     FMinimapHiliteLinesWithSelection
3922     );
3923 
3924   FillOneLine(NColorEntire, ARectLine.Left);
3925 
3926   //paint line
3927   if StrOutput<>'' then
3928   begin
3929     NColorAfter:= clNone;
3930 
3931     DoCalcLineHilite(
3932       WrapItem,
3933       ATempParts{%H-},
3934       NOutputCharsSkipped, cMaxCharsForOutput,
3935       NColorEntire, bLineColorForced,
3936       NColorAfter, false);
3937 
3938     //adapter may return ColorAfterEol, paint it
3939     if FOptShowFullHilite then
3940       if NColorAfter<>clNone then
3941         FillOneLine(NColorAfter, CurrPointText.X);
3942 
3943     //truncate text to not paint over screen
3944     NCount:= ARectLine.Width div ACharSize.XScaled div ATEditorCharXScale + 2;
3945     if Length(StrOutput)>NCount then
3946       SetLength(StrOutput, NCount);
3947 
3948     if StrOutput<>'' then
3949       CanvasTextOutMinimap(
3950         FMinimapBmp,
3951         ARectLine,
3952         CurrPointText.X - FRectMinimap.Left,
3953         CurrPointText.Y - FRectminimap.Top,
3954         ACharSize,
3955         FTabSize,
3956         ATempParts,
3957         FColorBG,
3958         NColorAfter,
3959         St.LineSub(
3960           WrapItem.NLineIndex,
3961           WrapItem.NCharIndex,
3962           FVisibleColumns), //optimize for huge lines
3963         bUseSetPixel
3964         );
3965   end
3966   else
3967   //paint empty line bg
3968   begin
3969     if FOptShowFullHilite then
3970     begin
3971       NColorAfter:= clNone;
3972       DoCalcPosColor(0, NLinesIndex, NColorAfter);
3973       if NColorAfter<>clNone then
3974         FillOneLine(NColorAfter, ARectLine.Left);
3975     end;
3976 
3977     {
3978     //TODO???
3979     DoPaintSelectedLineBG(C, ACharSize, ARectLine,
3980       CurrPoint,
3981       CurrPointText,
3982       WrapItem,
3983       0,
3984       AScrollHorz);
3985     }
3986   end;
3987 end;
3988 
3989 procedure TATSynEdit.DoPaintGutterOfLine(C: TCanvas; ARect: TRect; ACharSize: TATEditorCharSize;
3990   AWrapIndex: integer);
3991 var
3992   St: TATStrings;
3993   WrapItem: TATWrapItem;
3994   LineState: TATLineState;
3995   GutterItem: TATGutterItem;
3996   bLineWithCaret: boolean;
3997   NLinesIndex, NBandDecor: integer;
3998 begin
3999   St:= Strings;
4000   WrapItem:= FWrapInfo[AWrapIndex];
4001   NLinesIndex:= WrapItem.NLineIndex;
4002   if not St.IsIndexValid(NLinesIndex) then exit;
4003   bLineWithCaret:= IsLineWithCaret(NLinesIndex);
4004 
4005   Inc(ARect.Top, FTextOffsetFromTop);
4006 
4007   //paint area over scrolled text
4008   C.Brush.Color:= Colors.GutterBG;
4009   C.FillRect(FRectGutter.Left, ARect.Top, FRectGutter.Right, ARect.Bottom);
4010 
4011   //gutter band: number
4012   GutterItem:= FGutter[FGutterBandNumbers];
4013   if GutterItem.Visible then
4014   begin
4015     if bLineWithCaret and FOptShowGutterCaretBG then
4016     begin
4017       DoPaintGutterBandBG(C,
4018         Colors.GutterCaretBG,
4019         GutterItem.Left,
4020         ARect.Top,
4021         GutterItem.Right,
4022         ARect.Bottom,
4023         false);
4024       C.Font.Color:= Colors.GutterCaretFont;
4025     end
4026     else
4027       C.Font.Color:= Colors.GutterFont;
4028 
4029     if WrapItem.bInitial then
4030       DoPaintGutterNumber(C, NLinesIndex, ARect.Top, GutterItem);
4031   end;
4032 
4033   //gutter decor
4034   NBandDecor:= FGutterBandDecor;
4035   if NBandDecor<0 then
4036     NBandDecor:= FGutterBandBookmarks;
4037 
4038   GutterItem:= FGutter[NBandDecor];
4039   if GutterItem.Visible then
4040     if WrapItem.bInitial then
4041       DoPaintGutterDecor(C, NLinesIndex,
4042         Rect(
4043           GutterItem.Left,
4044           ARect.Top,
4045           GutterItem.Right,
4046           ARect.Bottom
4047           ));
4048 
4049   //gutter band: bookmark
4050   GutterItem:= FGutter[FGutterBandBookmarks];
4051   if GutterItem.Visible then
4052     if WrapItem.bInitial then
4053     begin
4054       if St.Bookmarks.Find(NLinesIndex)>=0 then
4055         DoEventDrawBookmarkIcon(C, NLinesIndex,
4056           Rect(
4057             GutterItem.Left,
4058             ARect.Top,
4059             GutterItem.Right,
4060             ARect.Bottom
4061             ));
4062     end;
4063 
4064   //gutter band: fold
4065   GutterItem:= FGutter[FGutterBandFolding];
4066   if GutterItem.Visible then
4067   begin
4068     DoPaintGutterBandBG(C,
4069       Colors.GutterFoldBG,
4070       GutterItem.Left,
4071       ARect.Top,
4072       GutterItem.Right,
4073       ARect.Bottom,
4074       false);
4075     DoPaintGutterFolding(C,
4076       AWrapIndex,
4077       GutterItem.Left,
4078       GutterItem.Right,
4079       ARect.Top,
4080       ARect.Bottom
4081       );
4082   end;
4083 
4084   //gutter band: state
4085   GutterItem:= FGutter[FGutterBandStates];
4086   if GutterItem.Visible then
4087   begin
4088     LineState:= St.LinesState[NLinesIndex];
4089     if LineState<>cLineStateNone then
4090       DoPaintGutterBandBG(C,
4091         FColorOfStates[LineState],
4092         GutterItem.Left,
4093         ARect.Top,
4094         GutterItem.Right,
4095         ARect.Bottom,
4096         false);
4097   end;
4098 
4099   //gutter band: separator
4100   GutterItem:= FGutter[FGutterBandSeparator];
4101   if GutterItem.Visible then
4102     DoPaintGutterBandBG(C,
4103       Colors.GutterSeparatorBG,
4104       GutterItem.Left,
4105       ARect.Top,
4106       GutterItem.Right,
4107       ARect.Bottom,
4108       false);
4109 
4110   //gutter band: empty indent
4111   GutterItem:= FGutter[FGutterBandEmpty];
4112   if GutterItem.Visible then
4113     DoPaintGutterBandBG(C,
4114       FColorBG,
4115       GutterItem.Left,
4116       ARect.Top,
4117       GutterItem.Right,
4118       ARect.Bottom,
4119       false);
4120 end;
4121 
4122 
GetMinimapSelTopnull4123 function TATSynEdit.GetMinimapSelTop: integer;
4124 begin
4125   Result:= FRectMinimap.Top + (Max(0, FScrollVert.NPos)-FScrollVertMinimap.NPos)*FCharSizeMinimap.Y;
4126 end;
4127 
GetMinimapActualHeightnull4128 function TATSynEdit.GetMinimapActualHeight: integer;
4129 begin
4130   Result:=
4131     Max(2, Min(
4132       FRectMinimap.Height,
4133       FWrapInfo.Count*FCharSizeMinimap.Y
4134       ));
4135 end;
4136 
GetMinimap_DraggedPosToWrapIndexnull4137 function TATSynEdit.GetMinimap_DraggedPosToWrapIndex(APosY: integer): integer;
4138 var
4139   NCount, NScrollPos, NScrollMax, NScrollMax2: integer;
4140 begin
4141   NCount:= FWrapInfo.Count;
4142   NScrollPos:= Max(0, APosY-FMouseDragMinimapDelta);
4143 
4144   //for big files
4145   NScrollMax:= Max(0, FRectMinimap.Height-FMouseDragMinimapSelHeight);
4146 
4147   //for small files: minimap drag must not be until bottom
4148   NScrollMax2:= NCount*FCharSizeMinimap.Y;
4149   if not FOptLastLineOnTop then
4150     NScrollMax2:= Max(0, NScrollMax2-FMouseDragMinimapSelHeight);
4151 
4152   if NScrollMax>NScrollMax2 then
4153     NScrollMax:= NScrollMax2;
4154 
4155   if NScrollMax>0 then
4156   begin
4157     Result:= Int64(FScrollVert.NPosLast) * NScrollPos div NScrollMax;
4158     Result:= Min(NCount-1, Result);
4159   end
4160   else
4161     Result:= 0;
4162 end;
4163 
GetMinimap_ClickedPosToWrapIndexnull4164 function TATSynEdit.GetMinimap_ClickedPosToWrapIndex(APosY: integer): integer;
4165 begin
4166   Result:= (APosY-FRectMinimap.Top) div FCharSizeMinimap.Y + FScrollVertMinimap.NPos;
4167   if not FWrapInfo.IsIndexValid(Result) then
4168     Result:= -1;
4169 end;
4170 
GetOptTextOffsetTopnull4171 function TATSynEdit.GetOptTextOffsetTop: integer;
4172 begin
4173   if ModeOneLine then
4174     Result:= (ClientHeight - TextCharSize.Y) div 2
4175   else
4176     Result:= FOptTextOffsetTop;
4177 end;
4178 
4179 function _IsColorDark(N: TColor): boolean;
4180 const
4181   cMax = $60;
4182 begin
4183   Result:= (Red(N)<cMax) and (Green(N)<cMax) and (Blue(N)<cMax);
4184 end;
4185 
4186 procedure TATSynEdit.DoPaintMinimapSelToBGRABitmap;
4187 var
4188   C: TBGRABitmap;
4189   R: TRect;
4190   rColor: TBGRAPixel;
4191 begin
4192   C:= FMinimapBmp;
4193   if FMinimapShowSelAlways or FCursorOnMinimap then
4194   begin
4195     GetRectMinimapSel(R);
4196     OffsetRect(R, -FRectMinimap.Left, -FRectMinimap.Top);
4197 
4198     // https://forum.lazarus.freepascal.org/index.php/topic,51383.msg377195.html#msg377195
4199     if _IsColorDark(FColorBG) then
4200       rColor.FromRGB(255, 255, 255, FMinimapSelColorChange*255 div 100)
4201     else
4202       rColor.FromRGB(0, 0, 0, FMinimapSelColorChange*255 div 100);
4203 
4204     C.FillRect(R, rColor, dmDrawWithTransparency);
4205 
4206     if FMinimapShowSelBorder then
4207     begin
4208       rColor.FromColor(Colors.MinimapBorder);
4209       C.Rectangle(R, rColor);
4210     end;
4211   end;
4212 
4213   if Colors.MinimapBorder<>clNone then
4214   begin
4215     rColor.FromColor(Colors.MinimapBorder);
4216     C.DrawVertLine(0, 0, FRectMinimap.Height, rColor);
4217   end;
4218 end;
4219 
4220 procedure TATSynEdit.DoPaintMinimapAllToBGRABitmap;
4221 begin
4222   //avoid too often minimap repainting
4223   if not FAdapterIsDataReady then exit;
4224 
4225   if ATEditorOptions.DebugTiming then
4226     FTickMinimap:= GetTickCount64;
4227 
4228   FScrollHorzMinimap.Clear;
4229   FScrollVertMinimap.Clear;
4230 
4231   FScrollVertMinimap.NPos:= GetMinimapScrollPos;
4232   FScrollVertMinimap.NPosLast:= MaxInt div 2;
4233 
4234   DoPaintMinimapTextToBGRABitmap(FRectMinimap, FCharSizeMinimap, FScrollHorzMinimap, FScrollVertMinimap);
4235   DoPaintMinimapSelToBGRABitmap;
4236 
4237   if ATEditorOptions.DebugTiming then
4238     FTickMinimap:= GetTickCount64-FTickMinimap;
4239 end;
4240 
4241 procedure TATSynEdit.DoPaintMicromap(C: TCanvas);
4242 begin
4243   if Assigned(FOnDrawMicromap) then
4244     FOnDrawMicromap(Self, C, FRectMicromap)
4245   else
4246   begin
4247     C.Brush.Color:= clCream;
4248     C.Brush.Style:= bsSolid;
4249     C.FillRect(FRectMicromap);
4250   end;
4251 end;
4252 
4253 
4254 procedure TATSynEdit.DoPaintGap(C: TCanvas; const ARect: TRect; AGap: TATGapItem);
4255 var
4256   RHere, RBmp: TRect;
4257   NColor: TColor;
4258 begin
4259   NColor:= AGap.Color;
4260   if NColor<>clNone then
4261   begin
4262     C.Brush.Color:= NColor;
4263     C.FillRect(ARect);
4264   end;
4265 
4266   if Assigned(AGap.Bitmap) then
4267   begin
4268     RBmp:= Rect(0, 0, AGap.Bitmap.Width, AGap.Bitmap.Height);
4269     //RHere is rect of bitmap's size, located at center of ARect
4270     RHere.Left:= GetGapBitmapPosLeft(ARect, AGap.Bitmap.Width);
4271     RHere.Top:= (ARect.Top+ARect.Bottom-RBmp.Bottom) div 2;
4272     RHere.Right:= RHere.Left + RBmp.Right;
4273     RHere.Bottom:= RHere.Top + RBmp.Bottom;
4274     C.CopyRect(RHere, AGap.Bitmap.Canvas, RBmp);
4275   end
4276   else
4277   if Assigned(AGap.Form) then
4278   begin
4279     AGap.Form.BorderStyle:= bsNone;
4280     AGap.Form.Parent:= Self;
4281 
4282     //RHere is rect of form, it is stretched by width to RectMain
4283     RHere.Left:= RectMain.Left;
4284     RHere.Right:= RectMain.Right;
4285     RHere.Top:= ARect.Top;
4286     RHere.Bottom:= RHere.Top + AGap.Size;
4287 
4288     AGap.Form.BoundsRect:= RHere;
4289     AGap.FormVisible:= true;
4290   end
4291   else
4292   if Assigned(FOnDrawGap) then
4293     FOnDrawGap(Self, C, ARect, AGap);
4294 end;
4295 
4296 procedure TATSynEdit.DoPaintMarginLineTo(C: TCanvas; AX, AWidth: integer; AColor: TColor);
4297 begin
4298   if (AX>=FRectMain.Left) and (AX<FRectMain.Right) then
4299   begin
4300     C.Pen.Color:= AColor;
4301     CanvasLineVert2(C, AX, FRectMain.Top, FRectMain.Bottom, false, AWidth);
4302   end;
4303 end;
4304 
4305 procedure TATSynEdit.DoPaintMargins(C: TCanvas);
4306   //
PosXnull4307   function PosX(NMargin: integer): integer; inline;
4308   begin
4309     Result:= FRectMain.Left + FCharSize.XScaled *(NMargin-FScrollHorz.NPos) div ATEditorCharXScale;
4310   end;
4311 var
4312   NWidth, i: integer;
4313 begin
4314   NWidth:= EditorScale(1);
4315   if FMarginRight>1 then
4316     DoPaintMarginLineTo(C, PosX(FMarginRight), NWidth, Colors.MarginRight);
4317   for i:= 0 to Length(FMarginList)-1 do
4318     DoPaintMarginLineTo(C, PosX(FMarginList[i]), NWidth, Colors.MarginUser);
4319 end;
4320 
4321 
4322 procedure TATSynEdit.DoPaintFoldedMark(C: TCanvas;
4323   APosX, APosY, ACoordX, ACoordY: integer;
4324   const AMarkText: string);
4325 var
4326   NWidth: integer;
4327   Str: string;
4328   RectMark: TRect;
4329   FoldMark: TATFoldedMark;
4330 begin
4331   Str:= AMarkText;
4332 
4333   SDeleteFrom(Str, #10);
4334     //e.g. Diff lexer gives collapsed-string with EOL (several lines)
4335 
4336   Str:= FTabHelper.TabsToSpaces(APosY, UTF8Decode(Str));
4337     //expand tabs too
4338 
4339   if APosX>0 then
4340     Inc(ACoordX, cFoldedMarkIndentOuter);
4341 
4342   //set colors:
4343   //if 1st chars selected, then use selection-color
4344   if IsPosSelected(APosX, APosY) and FOptShowFoldedMarkWithSelectionBG then
4345   begin
4346     if Colors.TextSelFont<>clNone then
4347       C.Font.Color:= Colors.TextSelFont
4348     else
4349       C.Font.Color:= Colors.TextFont;
4350     C.Brush.Color:= Colors.TextSelBG;
4351   end
4352   else
4353   begin
4354     C.Font.Color:= Colors.CollapseMarkFont;
4355     C.Brush.Color:= Colors.CollapseMarkBG;
4356   end;
4357 
4358   //paint text
4359   if not FOptShowFoldedMarkWithSelectionBG then
4360     C.Brush.Style:= bsClear;
4361 
4362   C.TextOut(
4363     ACoordX+cFoldedMarkIndentInner,
4364     ACoordY+FTextOffsetFromTop,
4365     Str);
4366   NWidth:= C.TextWidth(Str) + 2*cFoldedMarkIndentInner;
4367 
4368   //paint frame
4369   RectMark:= Rect(ACoordX, ACoordY, ACoordX+NWidth, ACoordY+FCharSize.Y);
4370   C.Pen.Color:= Colors.CollapseMarkBorder;
4371   C.Brush.Style:= bsClear;
4372   C.Rectangle(RectMark);
4373   C.Brush.Style:= bsSolid;
4374 
4375   if FFoldTooltipVisible then
4376   begin
4377     FoldMark.Init(
4378       RectMark,
4379       APosY,
4380       APosY + DoGetFoldedMarkLinesCount(APosY) -1
4381       );
4382 
4383     InitFoldedMarkList;
4384     FFoldedMarkList.Add(FoldMark);
4385   end;
4386 end;
4387 
GetMarginStringnull4388 function TATSynEdit.GetMarginString: string;
4389 var
4390   i: integer;
4391 begin
4392   Result:= '';
4393   for i:= 0 to Length(FMarginList)-1 do
4394     Result+= IntToStr(FMarginList[i]) + ' ';
4395   Result:= Trim(Result);
4396 end;
4397 
TATSynEdit.GetReadOnlynull4398 function TATSynEdit.GetReadOnly: boolean;
4399 begin
4400   Result:= Strings.ReadOnly;
4401 end;
4402 
GetLineTopnull4403 function TATSynEdit.GetLineTop: integer;
4404 var
4405   N: integer;
4406 begin
4407   if FLineTopTodo>0 then
4408     exit(FLineTopTodo);
4409   Result:= 0;
4410   if Assigned(FWrapInfo) and (FWrapInfo.Count>0) then
4411   begin
4412     N:= Max(0, FScrollVert.NPos);
4413     if FWrapInfo.IsIndexValid(N) then
4414       Result:= FWrapInfo[N].NLineIndex;
4415   end;
4416 end;
4417 
TATSynEdit.GetColumnLeftnull4418 function TATSynEdit.GetColumnLeft: integer;
4419 begin
4420   Result:= FScrollHorz.NPos;
4421 end;
4422 
4423 constructor TATSynEdit.Create(AOwner: TComponent);
4424 var
4425   i: integer;
4426 begin
4427   inherited;
4428 
4429   //GlobalCharSizer should be created after MainForm is inited
4430   if not Assigned(GlobalCharSizer) then
4431     GlobalCharSizer:= TATCharSizer.Create(AOwner);
4432 
4433   if not Assigned(cBitmapNiceScroll) then
4434     InitEditorResources;
4435 
4436   Caption:= '';
4437   ControlStyle:= ControlStyle+[csOpaque, csDoubleClicks, csTripleClicks];
4438   DoubleBuffered:= EditorDoubleBufferedNeeded;
4439   BorderStyle:= bsNone;
4440   TabStop:= true;
4441 
4442   Width:= 300;
4443   Height:= 250;
4444   Font.Name:= 'Courier New';
4445   Font.Size:= 9;
4446 
4447   FFontItalic:= TFont.Create;
4448   FFontItalic.Name:= '';
4449   FFontBold:= TFont.Create;
4450   FFontBold.Name:= '';
4451   FFontBoldItalic:= TFont.Create;
4452   FFontBoldItalic.Name:= '';
4453 
4454   FScrollbarVert:= TATScrollbar.Create(Self);
4455   FScrollbarVert.Hide;
4456   FScrollbarVert.Parent:= Self;
4457   FScrollbarVert.Align:= alRight;
4458   FScrollbarVert.Kind:= sbVertical;
4459   FScrollbarVert.Cursor:= crArrow;
4460   FScrollbarVert.Width:= ATScrollbarTheme.InitialSize;
4461   FScrollbarVert.Update;
4462   FScrollbarVert.OnChange:= @OnNewScrollbarVertChanged;
4463 
4464   FScrollbarHorz:= TATScrollbar.Create(Self);
4465   FScrollbarHorz.Hide;
4466   FScrollbarHorz.Parent:= Self;
4467   FScrollbarHorz.Align:= alBottom;
4468   FScrollbarHorz.Kind:= sbHorizontal;
4469   FScrollbarHorz.Cursor:= crArrow;
4470   FScrollbarHorz.Height:= ATScrollbarTheme.InitialSize;
4471   FScrollbarHorz.IndentCorner:= 100;
4472   FScrollbarHorz.Update;
4473   FScrollbarHorz.OnChange:= @OnNewScrollbarHorzChanged;
4474 
4475   FCaretShapeNormal:= TATCaretShape.Create;
4476   FCaretShapeOverwrite:= TATCaretShape.Create;
4477   FCaretShapeReadonly:= TATCaretShape.Create;
4478 
4479   FCaretShapeNormal.Width:= 2;
4480   FCaretShapeNormal.Height:= -100;
4481   FCaretShapeOverwrite.Width:= -100;
4482   FCaretShapeOverwrite.Height:= -100;
4483   FCaretShapeReadonly.Width:= -100;
4484   FCaretShapeReadonly.Height:= 2;
4485 
4486   FWantTabs:= true;
4487   FWantReturns:= true;
4488   FCharSize.XScaled:= 4 * ATEditorCharXScale;
4489   FCharSize.Y:= 4;
4490   FEditorIndex:= 0;
4491 
4492   //FWheelQueue:= TATEditorWheelQueue.Create;
4493 
4494   FCommandLog:= TATEditorCommandLog.Create;
4495 
4496   FCarets:= TATCarets.Create;
4497   FCarets.Add(0, 0);
4498 
4499   FCaretShowEnabled:= false; //code sets it On in DoEnter
4500   FCaretShown:= false;
4501   FCaretBlinkEnabled:= true;
4502   FCaretVirtual:= true;
4503   FCaretSpecPos:= false;
4504   FCaretStopUnfocused:= true;
4505   FCaretHideUnfocused:= true;
4506 
4507   FTabHelper:= TATStringTabHelper.Create;
4508   FMarkers:= nil;
4509   FAttribs:= nil;
4510   FMarkedRange:= nil;
4511   FDimRanges:= nil;
4512   FHotspots:= nil;
4513   FLinkCache:= TATLinkCache.Create;
4514 
4515   FMinimapBmp:= TBGRABitmap.Create;
4516 
4517   {$ifdef windows}
4518   FAdapterIME:= TATAdapterIMEStandard.Create;
4519   {$endif}
4520 
4521   FPaintLocked:= 0;
4522   FPaintFlags:= [cIntFlagBitmap];
4523 
4524   FColors:= TATEditorColors.Create;
4525   InitDefaultColors(FColors);
4526   InitEditorMouseActions(FMouseActions);
4527 
4528   FCursorText:= crIBeam;
4529   FCursorColumnSel:= crCross;
4530   FCursorGutterBookmark:= crHandPoint;
4531   FCursorGutterNumbers:= crDefault;
4532   FCursorMinimap:= crDefault;
4533   FCursorMicromap:= crDefault;
4534 
4535   FTimerDelayedParsing:= TTimer.Create(Self);
4536   FTimerDelayedParsing.Enabled:= false;
4537   FTimerDelayedParsing.Interval:= 300;
4538   FTimerDelayedParsing.OnTimer:= @TimerDelayedParsingTick;
4539 
4540   FTimerIdle:= TTimer.Create(Self);
4541   FTimerIdle.Enabled:= false;
4542   FTimerIdle.OnTimer:=@TimerIdleTick;
4543 
4544   FTimerBlink:= TTimer.Create(Self);
4545   FTimerBlink.Enabled:= false;
4546   SetCaretBlinkTime(cInitCaretBlinkTime);
4547   FTimerBlink.OnTimer:= @TimerBlinkTick;
4548 
4549   FTimerScroll:= TTimer.Create(Self);
4550   FTimerScroll.Enabled:= false;
4551   FTimerScroll.Interval:= cInitTimerAutoScroll;
4552   FTimerScroll.OnTimer:= @TimerScrollTick;
4553 
4554   FTimerNiceScroll:= TTimer.Create(Self);
4555   FTimerNiceScroll.Enabled:= false;
4556   FTimerNiceScroll.Interval:= cInitTimerNiceScroll;
4557   FTimerNiceScroll.OnTimer:= @TimerNiceScrollTick;
4558 
4559   FTimerFlicker:= TTimer.Create(Self);
4560   FTimerFlicker.Enabled:= false;
4561   FTimerFlicker.OnTimer:= @TimerFlickerTick;
4562 
4563   FBitmap:= Graphics.TBitmap.Create;
4564   FBitmap.PixelFormat:= pf24bit;
4565   FBitmap.SetSize(cInitBitmapWidth, cInitBitmapHeight);
4566 
4567   FOptUndoLimit:= cInitUndoLimit;
4568   FOptUndoIndentVert:= cInitUndoIndentVert;
4569   FOptUndoIndentHorz:= cInitUndoIndentHorz;
4570   FOptUndoMaxCarets:= cInitUndoMaxCarets;
4571   FOptUndoGrouped:= true;
4572   FOptUndoPause:= cInitUndoPause;
4573   FOptUndoPause2:= cInitUndoPause2;
4574   FOptUndoPauseHighlightLine:= cInitUndoPauseHighlightLine;
4575   FOptUndoForCaretJump:= cInitUndoForCaretJump;
4576 
4577   FStringsExternal:= nil;
4578   FStringsInt:= TATStrings.Create(FOptUndoLimit);
4579   FStringsInt.OnGetCaretsArray:= @GetCaretsArray;
4580   FStringsInt.OnGetMarkersArray:= @GetMarkersArray;
4581   FStringsInt.OnSetCaretsArray:= @SetCaretsArray;
4582   FStringsInt.OnSetMarkersArray:= @SetMarkersArray;
4583   FStringsInt.OnProgress:= @DoStringsOnProgress;
4584   FStringsInt.OnChangeEx:= @DoStringsOnChangeEx;
4585   FStringsInt.OnChangeLog:= @DoStringsOnChangeLog;
4586   FStringsInt.OnUndoBefore:= @DoStringsOnUndoBefore;
4587   FStringsInt.OnUndoAfter:= @DoStringsOnUndoAfter;
4588 
4589   FFold:= TATSynRanges.Create;
4590   FFoldStyle:= cInitFoldStyle;
4591   FFoldEnabled:= true;
4592   FFoldCacheEnabled:= true;
4593   FFoldUnderlineOffset:= cInitFoldUnderlineOffset;
4594   FFoldTooltipVisible:= cInitFoldTooltipVisible;
4595   FFoldTooltipWidthPercents:= cInitFoldTooltipWidthPercents;
4596   FFoldTooltipLineCount:= cInitFoldTooltipLineCount;
4597 
4598   FWrapInfo:= TATWrapInfo.Create;
4599   FWrapInfo.StringsObj:= FStringsInt;
4600   FWrapInfo.WrapColumn:= cInitMarginRight;
4601 
4602   FWrapTemps:= TATWrapItems.Create;
4603   FWrapUpdateNeeded:= true;
4604   FWrapMode:= cInitWrapMode;
4605   FWrapIndented:= true;
4606   FWrapAddSpace:= 1;
4607   FWrapEnabledForMaxLines:= cInitWrapEnabledForMaxLines;
4608 
4609   FMicromap:= TATMicromap.Create;
4610   FMicromapVisible:= cInitMicromapVisible;
4611   FMicromapOnScrollbar:= cInitMicromapOnScrollbar;
4612   FMicromapLineStates:= true;
4613   FMicromapSelections:= true;
4614   FMicromapBookmarks:= cInitMicromapBookmarks;
4615   FMicromapScaleDiv:= 1;
4616   FMicromapShowForMinCount:= cInitMicromapShowForMinCount;
4617 
4618   FOverwrite:= false;
4619   FTabSize:= cInitTabSize;
4620   FMarginRight:= cInitMarginRight;
4621   SetLength(FMarginList, 0);
4622   FFoldedMarkList:= nil;
4623 
4624   FOptInputNumberOnly:= false;
4625   FOptInputNumberAllowNegative:= cInitInputNumberAllowNegative;
4626   FOptMaskChar:= cInitMaskChar;
4627   FOptMaskCharUsed:= false;
4628   FOptScrollAnimationSteps:= cInitScrollAnimationSteps;
4629   FOptScrollAnimationSleep:= cInitScrollAnimationSleep;
4630   FOptIdleInterval:= cInitIdleInterval;
4631 
4632   FHighlightGitConflicts:= cInitHighlightGitConflicts;
4633   FOptAutoPairForMultiCarets:= cInitAutoPairForMultiCarets;
4634   FOptAutoPairChars:= '([{';
4635   FOptAutocompleteAutoshowCharCount:= 0;
4636   FOptAutocompleteTriggerChars:= '';
4637   FOptAutocompleteCommitChars:= ' ,;/\''"';
4638   FOptAutocompleteCloseChars:= '<>()[]{}=';
4639   FOptAutocompleteAddOpeningBracket:= true;
4640   FOptAutocompleteUpDownAtEdge:= 1; //cudWrap
4641 
4642   FShowOsBarVert:= false;
4643   FShowOsBarHorz:= false;
4644 
4645   FUnprintedVisible:= true;
4646   FUnprintedSpaces:= true;
4647   FUnprintedSpacesTrailing:= false;
4648   FUnprintedSpacesBothEnds:= false;
4649   FUnprintedSpacesOnlyInSelection:= false;
4650   FUnprintedEnds:= true;
4651   FUnprintedEndsDetails:= true;
4652   FUnprintedEof:= true;
4653 
4654   FTextHint:= '';
4655   FTextHintFontStyle:= [fsItalic];
4656   FTextHintCenter:= false;
4657 
4658   FGutter:= TATGutter.Create;
4659   FGutterDecor:= nil;
4660 
4661   FOptGutterVisible:= true;
4662   FOptGutterPlusSize:= cInitGutterPlusSize;
4663   FOptGutterShowFoldAlways:= true;
4664   FOptGutterShowFoldLines:= true;
4665   FOptGutterShowFoldLinesAll:= false;
4666   FOptGutterShowFoldLinesForCaret:= true;
4667   FOptGutterIcons:= cGutterIconsPlusMinus;
4668 
4669   FGutterDecorAlignment:= taCenter;
4670   FGutterBandBookmarks:= 0;
4671   FGutterBandNumbers:= 1;
4672   FGutterBandStates:= 2;
4673   FGutterBandFolding:= 3;
4674   FGutterBandSeparator:= 4;
4675   FGutterBandEmpty:= 5;
4676   FGutterBandDecor:= -1;
4677 
4678   for i:= 1 to cGutterBands do
4679     FGutter.Add(10);
4680   FGutter[FGutterBandBookmarks].Size:= cGutterSizeBm;
4681   FGutter[FGutterBandBookmarks].Scaled:= true;
4682   FGutter[FGutterBandNumbers].Size:= cGutterSizeNum;
4683   FGutter[FGutterBandStates].Size:= cGutterSizeState;
4684   FGutter[FGutterBandStates].Scaled:= true;
4685   FGutter[FGutterBandFolding].Size:= cGutterSizeFold;
4686   FGutter[FGutterBandFolding].Scaled:= true;
4687   FGutter[FGutterBandSeparator].Size:= cGutterSizeSep;
4688   FGutter[FGutterBandEmpty].Size:= cGutterSizeEmpty;
4689   FGutter[FGutterBandSeparator].Visible:= false;
4690   FGutter.Update;
4691 
4692   FOptNumbersAutosize:= true;
4693   FOptNumbersAlignment:= taRightJustify;
4694   FOptNumbersStyle:= cInitNumbersStyle;
4695   FOptNumbersShowFirst:= true;
4696   FOptNumbersShowCarets:= false;
4697   FOptNumbersIndentPercents:= cInitNumbersIndentPercents;
4698 
4699   FOptBorderVisible:= cInitBorderVisible;
4700   FOptBorderWidth:= cInitBorderWidth;
4701   FOptBorderWidthFocused:= cInitBorderWidthFocused;
4702   FOptBorderWidthMacro:= cInitBorderWidthMacro;
4703   FOptBorderFocusedActive:= false;
4704   FOptBorderMacroRecording:= true;
4705 
4706   FOptRulerVisible:= true;
4707   FOptRulerNumeration:= cInitRulerNumeration;
4708   FOptRulerHeightPercents:= cSizeRulerHeightPercents;
4709   FOptRulerMarkSizeCaret:= cSizeRulerMarkCaret;
4710   FOptRulerMarkSizeSmall:= cSizeRulerMarkSmall;
4711   FOptRulerMarkSizeBig:= cSizeRulerMarkBig;
4712   FOptRulerMarkForAllCarets:= false;
4713   FOptRulerFontSizePercents:= 80;
4714   FOptRulerTopIndentPercents:= 0;
4715 
4716   FMinimapWidth:= 150;
4717   FMinimapCharWidth:= 0;
4718   FMinimapCustomScale:= 0;
4719   FMinimapVisible:= cInitMinimapVisible;
4720   FMinimapShowSelBorder:= false;
4721   FMinimapShowSelAlways:= true;
4722   FMinimapSelColorChange:= cInitMinimapSelColorChange;
4723   FMinimapAtLeft:= false;
4724   FMinimapTooltipVisible:= cInitMinimapTooltipVisible;
4725   FMinimapTooltipLinesCount:= cInitMinimapTooltipLinesCount;
4726   FMinimapTooltipWidthPercents:= cInitMinimapTooltipWidthPercents;
4727   FMinimapHiliteLinesWithSelection:= true;
4728 
4729   FSpacingY:= cInitSpacingY;
4730   FCharSizeMinimap.XScaled:= 1 * ATEditorCharXScale;
4731   FCharSizeMinimap.Y:= 2;
4732 
4733   FOptScrollStyleHorz:= aessAuto;
4734   FOptScrollStyleVert:= aessShow;
4735   FOptScrollSmooth:= true;
4736   FOptScrollIndentCaretHorz:= 10;
4737   FOptScrollIndentCaretVert:= 0;
4738 
4739   FOptScrollbarsNew:= false;
4740   FOptScrollbarHorizontalAddSpace:= cInitScrollbarHorzAddSpace;
4741   FOptScrollLineCommandsKeepCaretOnScreen:= true;
4742 
4743   FOptShowFontLigatures:= true;
4744   FOptShowURLs:= true;
4745   FOptShowURLsRegex:= cUrlRegexInitial;
4746   FOptShowDragDropMarker:= true;
4747   FOptShowDragDropMarkerWidth:= cInitDragDropMarkerWidth;
4748   FOptShowFoldedMarkWithSelectionBG:= cInitShowFoldedMarkWithSelectionBG;
4749 
4750   FOptMaxLineLenToTokenize:= cInitMaxLineLenToTokenize;
4751   FOptMinLineLenToCalcURL:= cInitMinLineLenToCalcURL;
4752   FOptMaxLineLenToCalcURL:= cInitMaxLineLenToCalcURL;
4753   FOptMaxLinesToCountUnindent:= 100;
4754 
4755   FOptStapleStyle:= cLineStyleSolid;
4756   FOptStapleIndent:= -1;
4757   FOptStapleWidthPercent:= 100;
4758   FOptStapleHiliteActive:= true;
4759   FOptStapleHiliteActiveAlpha:= cInitStapleHiliteAlpha;
4760   FOptStapleEdge1:= cStapleEdgeAngle;
4761   FOptStapleEdge2:= cStapleEdgeAngle;
4762   FOptStapleIndentConsidersEnd:= false;
4763 
4764   FOptTextCenteringCharWidth:= 0;
4765   FOptTextOffsetLeft:= cInitTextOffsetLeft;
4766   FOptTextOffsetTop:= cInitTextOffsetTop;
4767   FOptAllowRepaintOnTextChange:= true;
4768   FOptAllowReadOnly:= true;
4769 
4770   FOptKeyBackspaceUnindent:= true;
4771   FOptKeyBackspaceGoesToPrevLine:= true;
4772   FOptKeyPageKeepsRelativePos:= true;
4773   FOptKeyUpDownNavigateWrapped:= true;
4774   FOptKeyUpDownAllowToEdge:= false;
4775   FOptKeyHomeEndNavigateWrapped:= true;
4776   FOptKeyUpDownKeepColumn:= true;
4777 
4778   FOptOverwriteAllowedOnPaste:= false;
4779   FOptNonWordChars:= cDefaultNonWordChars;
4780   FOptAutoIndent:= true;
4781   FOptAutoIndentKind:= cIndentAsPrevLine;
4782   FOptAutoIndentBetterBracketsCurly:= true;
4783   FOptAutoIndentBetterBracketsRound:= false;
4784   FOptAutoIndentBetterBracketsSquare:= false;
4785   FOptAutoIndentRegexRule:= '';
4786   FOptTabSpaces:= false;
4787 
4788   FOptLastLineOnTop:= false;
4789   FOptOverwriteSel:= true;
4790   FOptMouseDragDrop:= true;
4791   FOptMouseDragDropCopying:= true;
4792   FOptMouseDragDropCopyingWithState:= ssModifier;
4793   FOptMouseMiddleClickAction:= mcaScrolling;
4794   FOptMouseHideCursor:= false;
4795 
4796   FOptMouseClickOpensURL:= false;
4797   FOptMouseClickNumberSelectsLine:= true;
4798   FOptMouseClickNumberSelectsLineWithEOL:= true;
4799   FOptMouse2ClickAction:= cMouseDblClickSelectAnyChars;
4800   FOptMouse2ClickOpensURL:= true;
4801   FOptMouse2ClickDragSelectsWords:= true;
4802   FOptMouse3ClickSelectsLine:= true;
4803 
4804   FOptMouseRightClickMovesCaret:= false;
4805   FOptMouseWheelScrollVert:= true;
4806   FOptMouseWheelScrollVertSpeed:= 3;
4807   FOptMouseWheelScrollHorz:= true;
4808   FOptMouseWheelScrollHorzSpeed:= 10;
4809   FOptMouseWheelScrollHorzWithState:= ssShift;
4810   FOptMouseWheelZooms:= true;
4811   FOptMouseWheelZoomsWithState:= ssModifier;
4812 
4813   FOptCopyLinesIfNoSel:= true;
4814   FOptCutLinesIfNoSel:= false;
4815   FOptCopyColumnBlockAlignedBySpaces:= true;
4816   FOptShowFullSel:= false;
4817   FOptShowFullHilite:= true;
4818   FOptShowCurLine:= false;
4819   FOptShowCurLineMinimal:= true;
4820   FOptShowCurLineOnlyFocused:= false;
4821   FOptShowCurLineIfWithoutSel:= true;
4822   FOptShowCurColumn:= false;
4823   FOptShowMouseSelFrame:= cInitShowMouseSelFrame;
4824 
4825   FOptKeyPageUpDownSize:= cPageSizeFullMinus1;
4826   FOptKeyLeftRightGoToNextLineWithCarets:= true;
4827   FOptKeyLeftRightSwapSel:= true;
4828   FOptKeyLeftRightSwapSelAndSelect:= false;
4829   FOptKeyHomeToNonSpace:= true;
4830   FOptKeyEndToNonSpace:= true;
4831   FOptKeyTabIndents:= true;
4832   FOptKeyTabIndentsVerticalBlock:= false;
4833 
4834   FOptShowIndentLines:= true;
4835   FOptShowGutterCaretBG:= true;
4836   FOptIndentSize:= 2;
4837   FOptIndentKeepsAlign:= true;
4838   FOptIndentMakesWholeLinesSelection:= false;
4839   FOptSavingForceFinalEol:= false;
4840   FOptSavingTrimSpaces:= false;
4841   FOptShowScrollHint:= false;
4842   FOptCaretPreferLeftSide:= true;
4843   FOptCaretPosAfterPasteColumn:= cPasteCaretColumnRight;
4844   FOptCaretsAddedToColumnSelection:= true;
4845   FOptCaretFixAfterRangeFolded:= true;
4846   FOptCaretsPrimitiveColumnSelection:= cInitCaretsPrimitiveColumnSelection;
4847   FOptCaretsMultiToColumnSel:= cInitCaretsMultiToColumnSel;
4848   FOptCaretProximityVert:= 0;
4849   FOptMarkersSize:= cInitMarkerSize;
4850   FOptMouseEnableAll:= true;
4851   FOptMouseEnableNormalSelection:= true;
4852   FOptMouseEnableColumnSelection:= true;
4853   FOptPasteAtEndMakesFinalEmptyLine:= true;
4854   FOptPasteMultilineTextSpreadsToCarets:= true;
4855   FOptPasteWithEolAtLineStart:= true;
4856   FOptZebraActive:= false;
4857   FOptZebraStep:= 2;
4858   FOptZebraAlphaBlend:= cInitZebraAlphaBlend;
4859   FOptDimUnfocusedBack:= cInitDimUnfocusedBack;
4860 
4861   ClearMouseDownVariables;
4862   FMouseNiceScrollPos:= Point(0, 0);
4863 
4864   FSelRect:= cRectEmpty;
4865   ClearSelRectPoints;
4866   FCursorOnMinimap:= false;
4867   FCursorOnGutter:= false;
4868   FLastTextCmd:= 0;
4869   FLastTextCmdText:= '';
4870   FLastCommandChangedText:= false;
4871   FLastCommandDelayedParsingOnLine:= MaxInt;
4872   FLastHotspot:= -1;
4873 
4874   FScrollVert.Clear;
4875   FScrollHorz.Clear;
4876   FScrollVert.Vertical:= true;
4877   FScrollHorz.Vertical:= false;
4878   FScrollVertMinimap.Vertical:= true;
4879   FScrollHorzMinimap.Vertical:= false;
4880 
4881   FKeymap:= KeymapFull;
4882   FHintWnd:= nil;
4883 
4884   FMenuStd:= nil;
4885   FMenuText:= nil;
4886   FMenuGutterBm:= nil;
4887   FMenuGutterNum:= nil;
4888   FMenuGutterFold:= nil;
4889   FMenuGutterFoldStd:= nil;
4890   FMenuMinimap:= nil;
4891   FMenuMicromap:= nil;
4892   FMenuRuler:= nil;
4893 
4894   //must call UpdateTabHelper also before first Paint
4895   UpdateTabHelper;
4896   //must call before first paint
4897   UpdateLinksRegexObject;
4898 
4899   //allow Invalidate to work now
4900   IsRepaintEnabled:= true;
4901 end;
4902 
4903 destructor TATSynEdit.Destroy;
4904 begin
4905   if Assigned(FMinimapThread) then
4906   begin
4907     FMinimapThread.Terminate;
4908     FEventMapStart.SetEvent;
4909     if not FMinimapThread.Finished then
4910       FMinimapThread.WaitFor;
4911     FreeAndNil(FMinimapThread);
4912   end;
4913   if Assigned(FEventMapStart) then
4914     FreeAndNil(FEventMapStart);
4915   if Assigned(FEventMapDone) then
4916     FreeAndNil(FEventMapDone);
4917   FAdapterHilite:= nil;
4918   if Assigned(FMinimapTooltipBitmap) then
4919     FreeAndNil(FMinimapTooltipBitmap);
4920   if Assigned(FRegexLinks) then
4921     FreeAndNil(FRegexLinks);
4922   if Assigned(FAdapterIME) then
4923     FreeAndNil(FAdapterIME);
4924   TimersStop;
4925   if Assigned(FHintWnd) then
4926     FreeAndNil(FHintWnd);
4927   if Assigned(FMenuStd) then
4928     FreeAndNil(FMenuStd);
4929   TimerBlinkDisable;
4930   if Assigned(FFoldedMarkList) then
4931   begin
4932     FFoldedMarkList.Clear;
4933     FreeAndNil(FFoldedMarkList);
4934   end;
4935   FreeAndNil(FMinimapBmp);
4936   FreeAndNil(FMicromap);
4937   FreeAndNil(FFold);
4938   FreeAndNil(FTimerFlicker);
4939   FreeAndNil(FTimerDelayedParsing);
4940   FreeAndNil(FTimerNiceScroll);
4941   FreeAndNil(FTimerScroll);
4942   FreeAndNil(FTimerBlink);
4943   FreeAndNil(FCarets);
4944   FreeAndNil(FCommandLog);
4945   if Assigned(FHotspots) then
4946     FreeAndNil(FHotspots);
4947   if Assigned(FDimRanges) then
4948     FreeAndNil(FDimRanges);
4949   if Assigned(FMarkedRange) then
4950     FreeAndNil(FMarkedRange);
4951   if Assigned(FMarkers) then
4952     FreeAndNil(FMarkers);
4953   FreeAndNil(FTabHelper);
4954   if Assigned(FAttribs) then
4955     FreeAndNil(FAttribs);
4956   FreeAndNil(FGutter);
4957   FreeAndNil(FWrapTemps);
4958   FreeAndNil(FWrapInfo);
4959   FreeAndNil(FStringsInt);
4960   if Assigned(FGutterDecor) then
4961     FreeAndNil(FGutterDecor);
4962   FreeAndNil(FBitmap);
4963   FreeAndNil(FColors);
4964   FreeAndNil(FLinkCache);
4965   FreeAndNil(FFontItalic);
4966   FreeAndNil(FFontBold);
4967   FreeAndNil(FFontBoldItalic);
4968   FreeAndNil(FCaretShapeNormal);
4969   FreeAndNil(FCaretShapeOverwrite);
4970   FreeAndNil(FCaretShapeReadonly);
4971   //FreeAndNil(FWheelQueue);
4972   inherited;
4973 end;
4974 
4975 procedure TATSynEdit.Update(AUpdateWrapInfo: boolean=false);
4976 begin
4977   if not IsRepaintEnabled then exit;
4978 
4979   UpdateCursor;
4980 
4981   if AUpdateWrapInfo then
4982     FWrapUpdateNeeded:= true;
4983 
4984   Invalidate;
4985 end;
4986 
4987 procedure TATSynEdit.SetFocus;
4988 begin
4989   if HandleAllocated then
4990     LCLIntf.SetFocus(Handle);
4991 end;
4992 
4993 procedure TATSynEdit.GetClientSizes(out W, H: integer);
4994 begin
4995   W:= Width;
4996   H:= Height;
4997   if ModeOneLine then exit;
4998 
4999   if FOptScrollbarsNew then //better check this instead of FScrollbarVert.Visible
5000   begin
5001     Dec(W, FScrollbarVert.Width);
5002   end
5003   else
5004   begin
5005     W:= inherited ClientWidth;
5006   end;
5007 
5008   if FScrollbarHorz.Visible then
5009     Dec(H, FScrollbarHorz.Height);
5010 
5011   if W<1 then W:= 1;
5012   if H<1 then H:= 1;
5013 end;
5014 
5015 procedure TATSynEdit.LoadFromFile(const AFilename: string; AKeepScroll: boolean=false);
5016 begin
5017   TimerBlinkDisable;
5018 
5019   FCarets.Clear;
5020   FCarets.Add(0, 0);
5021 
5022   Strings.Clear(false{AWithEvent});
5023   FWrapInfo.Clear;
5024   FWrapUpdateNeeded:= true;
5025 
5026   if not AKeepScroll then
5027   begin
5028     FScrollHorz.Clear;
5029     FScrollVert.Clear;
5030   end;
5031 
5032   BeginUpdate;
5033   try
5034     FFileName:= '';
5035     Strings.LoadFromFile(AFilename);
5036     FFileName:= AFileName;
5037   finally
5038     EndUpdate;
5039   end;
5040 
5041   Update;
5042   TimerBlinkEnable;
5043 
5044   DoEventChange(0, false{AllowOnChange}); //calling OnChange makes almost no sense on opening file
5045 
5046   //DoEventCarets; //calling OnChangeCaretPos makes little sense on opening file
5047 end;
5048 
5049 procedure TATSynEdit.SaveToFile(const AFilename: string);
5050 var
5051   St: TATStrings;
5052   bChange1, bChange2, bChange3: boolean;
5053 begin
5054   St:= Strings;
5055   bChange1:= false;
5056   bChange2:= false;
5057   bChange3:= false;
5058 
5059   if FOptSavingForceFinalEol then
5060     bChange1:= St.ActionEnsureFinalEol;
5061 
5062   if FOptSavingTrimSpaces then
5063   begin
5064     bChange2:= St.ActionTrimSpaces(cTrimRight);
5065     //caret may be after end-of-line, so fix it
5066     if not OptCaretVirtual then
5067       DoCaretsFixIncorrectPos(true);
5068   end;
5069 
5070   if FOptSavingTrimFinalEmptyLines then
5071   begin
5072     bChange3:= St.ActionTrimFinalEmptyLines;
5073     if bChange3 then
5074       DoCaretsFixIncorrectPos(false);
5075   end;
5076 
5077   if bChange1 or bChange2 or bChange3 then
5078   begin
5079     Update(true);
5080     DoEventChange;
5081   end;
5082 
5083   St.SaveToFile(AFilename);
5084   FFileName:= AFilename;
5085   Modified:= false;
5086 end;
5087 
5088 
GetStringsnull5089 function TATSynEdit.GetStrings: TATStrings;
5090 begin
5091   if Assigned(FStringsExternal) then
5092     Result:= FStringsExternal
5093   else
5094     Result:= FStringsInt;
5095 end;
5096 
5097 procedure TATSynEdit.SetCaretBlinkTime(AValue: integer);
5098 begin
5099   AValue:= Max(AValue, cMinCaretTime);
5100   AValue:= Min(AValue, cMaxCaretTime);
5101   FCaretBlinkTime:= AValue;
5102   FTimerBlink.Interval:= AValue;
5103 end;
5104 
5105 procedure TATSynEdit.SetSpacingY(AValue: integer);
5106 begin
5107   if FSpacingY=AValue then Exit;
5108   FSpacingY:= AValue;
5109   FWrapUpdateNeeded:= true;
5110 end;
5111 
5112 procedure TATSynEdit.SetMarginString(const AValue: string);
5113 var
5114   Sep: TATStringSeparator;
5115   N: integer;
5116 begin
5117   SetLength(FMarginList, 0);
5118   Sep.Init(AValue, ' ');
5119   repeat
5120     if not Sep.GetItemInt(N, 0) then Break;
5121     if N<2 then Continue;
5122     SetLength(FMarginList, Length(FMarginList)+1);
5123     FMarginList[Length(FMarginList)-1]:= N;
5124   until false;
5125 end;
5126 
5127 procedure TATSynEdit.SetMicromapVisible(AValue: boolean);
5128 begin
5129   if FMicromapVisible=AValue then Exit;
5130   FMicromapVisible:= AValue;
5131   if not FMicromapOnScrollbar then
5132     FWrapUpdateNeeded:= true;
5133 end;
5134 
5135 procedure TATSynEdit.SetMinimapVisible(AValue: boolean);
5136 begin
5137   if FMinimapVisible=AValue then Exit;
5138   FMinimapVisible:= AValue;
5139   FWrapUpdateNeeded:= true;
5140 end;
5141 
5142 procedure TATSynEdit.SetOneLine(AValue: boolean);
5143 var
5144   St: TATStrings;
5145 begin
5146   Carets.OneLine:= AValue;
5147   St:= Strings;
5148   St.OneLine:= AValue;
5149 
5150   if AValue then
5151   begin
5152     OptGutterVisible:= false;
5153     OptRulerVisible:= false;
5154     OptMinimapVisible:= false;
5155     //OptMicromapVisible:= false;
5156     OptCaretVirtual:= false;
5157     OptCaretManyAllowed:= false;
5158     OptUnprintedVisible:= false;
5159     OptWrapMode:= cWrapOff;
5160     OptScrollStyleHorz:= aessHide;
5161     OptScrollStyleVert:= aessHide;
5162     OptMouseMiddleClickAction:= mcaNone;
5163     OptMouseDragDrop:= false;
5164     OptMarginRight:= 1000;
5165     OptUndoLimit:= 200;
5166 
5167     DoCaretSingle(0, 0);
5168 
5169     while St.Count>1 do
5170       St.LineDelete(St.Count-1, false, false, false);
5171   end;
5172 end;
5173 
5174 procedure TATSynEdit.SetReadOnly(AValue: boolean);
5175 begin
5176   if not FOptAllowReadOnly then Exit;
5177   Strings.ReadOnly:= AValue;
5178 end;
5179 
5180 procedure TATSynEdit.SetLineTop(AValue: integer);
5181 begin
5182   if not HandleAllocated then
5183   begin
5184     FLineTopTodo:= AValue;
5185     exit;
5186   end;
5187 
5188   if AValue<=0 then
5189   begin
5190     FScrollVert.SetZero;
5191     Update;
5192     Exit
5193   end;
5194 
5195   //first make sure WrapInfo is filled with data;
5196   //then we can read WrapInfo and calc scroll pos;
5197   //this is required for restoring LineTop for n tabs, on opening CudaText.
5198   UpdateWrapInfo;
5199 
5200   DoScroll_LineTop(AValue, true);
5201 end;
5202 
5203 procedure TATSynEdit.DoScroll_SetPos(var AScrollInfo: TATEditorScrollInfo; APos: integer);
5204 begin
5205   AScrollInfo.NPos:= APos;
5206   //must update other info in AScrollInfo
5207   UpdateScrollbars(true);
5208 end;
5209 
5210 procedure TATSynEdit.DoScroll_LineTop(ALine: integer; AUpdate: boolean);
5211 var
5212   NFrom, NTo, i: integer;
5213 begin
5214   if FWrapInfo=nil then exit;
5215 
5216   if (ALine<=0) or (FWrapInfo.Count=0) then
5217   begin
5218     FScrollVert.SetZero;
5219     if AUpdate then Update;
5220     Exit
5221   end;
5222 
5223   //find exact match
5224   FWrapInfo.FindIndexesOfLineNumber(ALine, NFrom, NTo);
5225   if NFrom>=0 then
5226   begin
5227     DoScroll_SetPos(FScrollVert, NFrom);
5228     if AUpdate then Update;
5229     Exit
5230   end;
5231 
5232   //find approx match
5233   for i:= 0 to FWrapInfo.Count-1 do
5234     with FWrapInfo[i] do
5235       if NLineIndex>=ALine then
5236       begin
5237         DoScroll_SetPos(FScrollVert, i);
5238         if AUpdate then Update;
5239         Exit
5240       end;
5241 end;
5242 
5243 procedure TATSynEdit.SetColumnLeft(AValue: integer);
5244 begin
5245   DoScroll_SetPos(FScrollHorz, AValue);
5246   Update;
5247 end;
5248 
5249 procedure TATSynEdit.SetLinesFromTop(AValue: integer);
5250 begin
5251   with FScrollVert do
5252     NPos:= Max(0, Min(NPosLast, NPos + (GetLinesFromTop - AValue)));
5253 end;
5254 
5255 procedure TATSynEdit.SetRedoAsString(const AValue: string);
5256 begin
5257   Strings.RedoAsString:= AValue;
5258 end;
5259 
5260 procedure TATSynEdit.SetStrings(Obj: TATStrings);
5261 begin
5262   FStringsExternal:= Obj;
5263 end;
5264 
TATSynEdit.GetTextOffsetnull5265 function TATSynEdit.GetTextOffset: TPoint;
5266 var
5267   NGutterWidth: integer;
5268 begin
5269   if ModeOneLine then
5270   begin
5271     Result.X:= OptTextOffsetLeft;
5272     Result.Y:= OptTextOffsetTop;
5273     exit;
5274   end;
5275 
5276   if FOptGutterVisible then
5277     NGutterWidth:= Gutter.Width
5278   else
5279     NGutterWidth:= 0;
5280 
5281   if FOptTextCenteringCharWidth>0 then
5282     Result.X:= Max(0, (ClientWidth - NGutterWidth -
5283                        FOptTextCenteringCharWidth * FCharSize.XScaled div ATEditorCharXScale) div 2)
5284   else
5285     Result.X:= OptTextOffsetLeft;
5286 
5287   Inc(Result.X, NGutterWidth);
5288 
5289   Result.Y:= OptTextOffsetTop;
5290 
5291   if FSpacingY<0 then
5292     Result.Y:= Max(Result.Y, -FSpacingY*2); //*2 is needed to not clip the first line
5293 
5294   if FOptRulerVisible then
5295     Inc(Result.Y, FRulerHeight);
5296 end;
5297 
TATSynEdit.GetPageLinesnull5298 function TATSynEdit.GetPageLines: integer;
5299 begin
5300   case FOptKeyPageUpDownSize of
5301     cPageSizeFull:
5302       Result:= GetVisibleLines;
5303     cPageSizeFullMinus1:
5304       Result:= GetVisibleLines-1;
5305     cPageSizeHalf:
5306       Result:= GetVisibleLines div 2;
5307   end;
5308 end;
5309 
5310 procedure TATSynEdit.DoPaintAll(C: TCanvas; ALineFrom: integer);
5311 var
5312   NColorOther: TColor;
5313 begin
5314   UpdateInitialVars(C);
5315 
5316   if Enabled then
5317   begin
5318     FColorFont:= Colors.TextFont;
5319     FColorBG:= Colors.TextBG;
5320     if FOptDimUnfocusedBack<>0 then
5321       if not _IsFocused then
5322       begin
5323         if FOptDimUnfocusedBack>0 then
5324           NColorOther:= clBlack
5325         else
5326           NColorOther:= clWhite;
5327         FColorBG:= ColorBlend(NColorOther, FColorBG, Abs(FOptDimUnfocusedBack));
5328       end;
5329   end
5330   else
5331   begin
5332     FColorFont:= Colors.TextDisabledFont;
5333     FColorBG:= Colors.TextDisabledBG;
5334   end;
5335 
5336   Inc(FPaintCounter);
5337   FVisibleColumns:= GetVisibleColumns;
5338   FCaretShown:= false;
5339   Carets.GetSelections(FSel);
5340 
5341   if Assigned(FAdapterHilite) then
5342     FAdapterIsDataReady:= FAdapterHilite.IsDataReady
5343   else
5344     FAdapterIsDataReady:= true;
5345 
5346   UpdateGapForms(true);
5347   DoPaintMain(C, ALineFrom);
5348   UpdateGapForms(false);
5349   UpdateCaretsCoords;
5350 
5351   if Carets.Count>0 then
5352   begin
5353     if FOptShowCurColumn then
5354       DoPaintMarginLineTo(C, Carets[0].CoordX, EditorScale(1), Colors.MarginCaret);
5355 
5356     DoPaintRulerCaretMarks(C);
5357   end;
5358 
5359   DoPaintMarkersTo(C);
5360 end;
5361 
DoPaintnull5362 function TATSynEdit.DoPaint(ALineFrom: integer): boolean;
5363 //gets True if one of scrollbars changed Visible state
5364 begin
5365   if csLoading in ComponentState then
5366     exit(false);
5367 
5368   UpdateTabHelper;
5369 
5370   if DoubleBuffered then
5371   begin
5372     if Assigned(FBitmap) then
5373       if cIntFlagBitmap in FPaintFlags then
5374       begin
5375         FBitmap.BeginUpdate(true);
5376         try
5377           DoPaintAll(FBitmap.Canvas, ALineFrom);
5378         finally
5379           FBitmap.EndUpdate();
5380         end;
5381       end;
5382   end
5383   else
5384     DoPaintAll(Canvas, ALineFrom);
5385 
5386   Result:= UpdateScrollbars(false);
5387 end;
5388 
5389 procedure TATSynEdit.DoPaintLockedWarning(C: TCanvas);
5390 const
5391   cBitmapX = 20;
5392   cBitmapY = 20;
5393   cRectX = 85;
5394   cRectY = 40;
5395   cRectWidth = 300;
5396   cRectHeight = 10;
5397 var
5398   NValue: integer;
5399   Bmp: TGraphic;
5400 begin
5401   C.Brush.Color:= Colors.TextBG;
5402   C.FillRect(Rect(0, 0, Width, Height));
5403 
5404   if Strings.ProgressKind<>cStringsProgressSaving then
5405     Bmp:= cBitmapWait
5406   else
5407     Bmp:= cBitmapSaving;
5408   C.Draw(cBitmapX, cBitmapY, Bmp);
5409 
5410   NValue:= Strings.ProgressValue;
5411   if NValue>0 then
5412   begin
5413     C.Pen.Color:= Colors.TextSelBG;
5414     C.Brush.Color:= Colors.TextSelBG;
5415     C.FrameRect(
5416       cRectX,
5417       cRectY,
5418       cRectX + cRectWidth,
5419       cRectY + cRectHeight
5420       );
5421     C.FillRect(
5422       cRectX,
5423       cRectY,
5424       cRectX + cRectWidth * NValue div 100,
5425       cRectY + cRectHeight
5426       );
5427   end;
5428 end;
5429 
5430 
5431 procedure TATSynEdit.Paint;
5432 var
5433   NLine: integer;
5434 begin
5435   if not HandleAllocated then exit;
5436 
5437   FPaintWorking:= true;
5438   try
5439     if cIntFlagResize in FPaintFlags then
5440     begin
5441       Exclude(FPaintFlags, cIntFlagResize);
5442       if DoubleBuffered then
5443         if Assigned(FBitmap) then
5444           BitmapResizeBySteps(FBitmap, Width, Height);
5445     end;
5446 
5447     NLine:= -1;
5448     if FLineTopTodo>0 then
5449     begin
5450       NLine:= FLineTopTodo;
5451       FLineTopTodo:= 0;
5452     end;
5453 
5454     FPaintStarted:= true;
5455     PaintEx(NLine);
5456   finally
5457     FPaintWorking:= false;
5458   end;
5459 end;
5460 
IsNormalLexerActivenull5461 function TATSynEdit.IsNormalLexerActive: boolean;
5462 var
5463   S: string;
5464 begin
5465   if FAdapterHilite=nil then
5466     exit(false);
5467   S:= FAdapterHilite.GetLexerName;
5468   if S='-' then //none lexer
5469     exit(false);
5470   if SEndsWith(S, ' ^') then //lite lexer
5471     exit(false);
5472   Result:= true;
5473 end;
5474 
5475 procedure TATSynEdit.SetEditorIndex(AValue: integer);
5476 begin
5477   if FEditorIndex=AValue then Exit;
5478   FEditorIndex:= AValue;
5479   FWrapInfo.EditorIndex:= AValue;
5480 end;
5481 
5482 procedure TATSynEdit.PaintEx(ALineNumber: integer);
5483 var
5484   R: TRect;
5485 begin
5486   //experimental, reduce flickering on typing in Markdown
5487   FOptAllowRepaintOnTextChange:= not IsNormalLexerActive;
5488 
5489   if IsLocked then
5490   begin
5491     DoPaintLockedWarning(Canvas);
5492     Exit
5493   end;
5494 
5495   if DoubleBuffered then
5496     if not Assigned(FBitmap) then exit;
5497 
5498   if ATEditorOptions.DebugTiming then
5499   begin
5500     FTickAll:= GetTickCount64;
5501     FTickMinimap:= 0;
5502   end;
5503 
5504   //if scrollbars shown, paint again
5505   if DoPaint(ALineNumber) then
5506     DoPaint(ALineNumber);
5507   Exclude(FPaintFlags, cIntFlagBitmap);
5508 
5509   if DoubleBuffered then
5510   //buf mode: timer tick don't give painting of whole bitmap
5511   //(cIntFlagBitmap off)
5512   begin
5513     DoPaintCarets(FBitmap.Canvas, true);
5514   end
5515   else
5516   //non-buf mode: timer tick clears whole canvas first.
5517   //we already painted bitmap above,
5518   //and now we invert carets or dont invert (use FCaretAllowNextBlink)
5519   begin
5520     if not FCaretBlinkEnabled or FCaretAllowNextBlink then
5521       DoPaintCarets(Canvas, true);
5522   end;
5523 
5524   if DoubleBuffered then
5525   begin
5526     //single place where we flush bitmap to canvas
5527     R:= Canvas.ClipRect;
5528     Canvas.CopyRect(R, FBitmap.Canvas, R);
5529   end;
5530 
5531   DoPaintMarkerOfDragDrop(Canvas);
5532 
5533   if ATEditorOptions.DebugTiming then
5534   begin
5535     FTickAll:= GetTickCount64-FTickAll;
5536     DoPaintTiming(Canvas);
5537   end;
5538 end;
5539 
5540 procedure TATSynEdit.Resize;
5541 begin
5542   inherited;
5543   if not IsRepaintEnabled then exit;
5544 
5545   //avoid setting FLineTopTodo, which breaks the v-scroll-pos, if huge line is wrapped
5546   //and v-scroll-pos is in the middle of this line
5547   if (Width=FLastControlWidth) and
5548     (Height=FLastControlHeight) then exit;
5549   FLastControlWidth:= Width;
5550   FLastControlHeight:= Height;
5551 
5552   FLineTopTodo:= GetLineTop;
5553 
5554   Include(FPaintFlags, cIntFlagResize);
5555   if FWrapMode in [cWrapOn, cWrapAtWindowOrMargin] then
5556     FWrapUpdateNeeded:= true;
5557 
5558   if not FPaintStarted then exit;
5559   Invalidate;
5560 end;
5561 
5562 procedure TATSynEdit.DoContextPopup(MousePos: TPoint; var Handled: Boolean);
5563 begin
5564   InitMenuStd;
5565   inherited;
5566   if not Handled then
5567   begin
5568     DoHandleRightClick(MousePos.X, MousePos.Y);
5569     Handled:= true;
5570   end;
5571 end;
5572 
5573 procedure TATSynEdit.WMEraseBkgnd(var Msg: TLMEraseBkgnd);
5574 begin
5575   //needed to remove flickering on resize and mouse-over
5576   Msg.Result:= 1;
5577 end;
5578 
5579 procedure TATSynEdit.DoHintShow;
5580 var
5581   S: string;
5582   P: TPoint;
5583   R: TRect;
5584 begin
5585   if csDesigning in ComponentState then Exit;
5586   if not FOptShowScrollHint then Exit;
5587 
5588   if FHintWnd=nil then
5589     FHintWnd:= THintWindow.Create(Self);
5590 
5591   S:= cTextHintScrollPrefix+' '+IntToStr(LineTop+1);
5592   R:= FHintWnd.CalcHintRect(500, S, nil);
5593 
5594   P:= ClientToScreen(Point(ClientWidth-R.Width, 0));
5595   OffsetRect(R, P.X, P.Y);
5596   OffsetRect(R, -cHintScrollDx, cHintScrollDx);
5597 
5598   FHintWnd.ActivateHint(R, S);
5599   FHintWnd.Invalidate; //for Win
5600 end;
5601 
5602 procedure TATSynEdit.DoHintShowForBookmark(ALine: integer);
5603 var
5604   S: string;
5605   P: TPoint;
5606   R: TRect;
5607   NIndex: integer;
5608 begin
5609   if csDesigning in ComponentState then Exit;
5610 
5611   if FHintWnd=nil then
5612     FHintWnd:= THintWindow.Create(Self);
5613 
5614   NIndex:= Strings.Bookmarks.Find(ALine);
5615   if NIndex<0 then exit;
5616 
5617   S:= Strings.Bookmarks[NIndex]^.Data.Hint;
5618   if S='' then
5619     begin DoHintHide; exit end;
5620 
5621   R:= FHintWnd.CalcHintRect(500, S, nil);
5622 
5623   P:= Mouse.CursorPos;
5624   OffsetRect(R, P.X+cHintBookmarkDx, P.Y+cHintBookmarkDy);
5625 
5626   FHintWnd.ActivateHint(R, S);
5627   FHintWnd.Invalidate; //for Win
5628 end;
5629 
5630 
5631 procedure TATSynEdit.DoHintHide;
5632 begin
5633   if Assigned(FHintWnd) then
5634     FHintWnd.Hide;
5635 end;
5636 
5637 procedure _UpdateScrollInfoFromSmoothPos(
5638   var AInfo: TATEditorScrollInfo;
5639   const APos: Int64;
5640   AWrapInfo: TATWrapInfo;
5641   AGaps: TATGaps);
5642 //Note: for vertical bar, NPos=-1 means than we are before the first line, over top gap
5643 var
5644   NPos, NPixels, NLineIndex, NCharSize: Int64;
5645   NSizeGapTop, NSizeGap0: Int64;
5646   bConsiderGaps: boolean;
5647 begin
5648   AInfo.SmoothPos:= APos;
5649   bConsiderGaps:= AInfo.Vertical and (AGaps.Count>0);
5650 
5651   if APos<=0 then
5652   begin
5653     AInfo.SetZero;
5654     if bConsiderGaps then
5655       if AGaps.SizeOfGapTop>0 then
5656         AInfo.NPos:= -1;
5657     exit
5658   end;
5659 
5660   if APos>=AInfo.SmoothPosLast then
5661   begin
5662     AInfo.SetLast;
5663     exit
5664   end;
5665 
5666   if bConsiderGaps then
5667   begin
5668     //for position before line=0
5669     NSizeGapTop:= AGaps.SizeOfGapTop;
5670     NSizeGap0:= AGaps.SizeOfGap0;
5671 
5672     if NSizeGapTop>0 then
5673       if APos<NSizeGapTop then
5674       begin
5675         AInfo.NPos:= -1;
5676         AInfo.NPixelOffset:= APos;
5677         exit;
5678       end;
5679 
5680     //for position before line=1
5681     //(other positions are calculated ok later)
5682     if NSizeGap0>0 then
5683       if APos<NSizeGapTop+AInfo.SmoothCharSize+NSizeGap0 then
5684       begin
5685         AInfo.NPos:= 0;
5686         AInfo.NPixelOffset:= APos-NSizeGapTop;
5687         exit;
5688       end;
5689   end;
5690 
5691   NCharSize:= AInfo.SmoothCharSize;
5692   AInfo.NPos:= Min(APos div NCharSize, AInfo.NMax);
5693   AInfo.NPixelOffset:= APos mod NCharSize;
5694 
5695   //consider Gaps for vert scrolling
5696   if bConsiderGaps then
5697   begin
5698     NPos:= Min(AInfo.NPos, AWrapInfo.Count-1);
5699     NPixels:= AInfo.NPixelOffset;
5700 
5701     repeat
5702       NLineIndex:= AWrapInfo.Data[NPos].NLineIndex - 1;
5703       NPixels:= APos - NPos*NCharSize - AGaps.SizeForLineRange(-1, NLineIndex);
5704       if NPos=0 then Break;
5705       if NLineIndex=0 then Break;
5706       if NPixels>=0 then Break;
5707       Dec(NPos);
5708     until false;
5709 
5710     AInfo.NPos:= NPos;
5711     AInfo.NPixelOffset:= NPixels
5712   end;
5713 end;
5714 
5715 procedure TATSynEdit.UpdateScrollInfoFromSmoothPos(var AInfo: TATEditorScrollInfo; const APos: Int64);
5716 begin
5717   _UpdateScrollInfoFromSmoothPos(AInfo, APos, WrapInfo, Gaps);
5718 end;
5719 
UpdateScrollInfoFromMessagenull5720 function TATSynEdit.UpdateScrollInfoFromMessage(var Info: TATEditorScrollInfo; const Msg: TLMScroll): boolean;
5721 begin
5722   if Info.NMax<Info.NPage then
5723   begin
5724     Info.Clear;
5725     Exit(true);
5726   end;
5727 
5728   case Msg.ScrollCode of
5729     SB_TOP:
5730       begin
5731         UpdateScrollInfoFromSmoothPos(Info, 0);
5732       end;
5733 
5734     SB_BOTTOM:
5735       begin
5736         UpdateScrollInfoFromSmoothPos(Info, Info.SmoothPosLast);
5737       end;
5738 
5739     SB_LINEUP:
5740       begin
5741         UpdateScrollInfoFromSmoothPos(Info, Info.SmoothPos-Info.SmoothCharSize);
5742       end;
5743 
5744     SB_LINEDOWN:
5745       begin
5746         UpdateScrollInfoFromSmoothPos(Info, Info.SmoothPos+Info.SmoothCharSize);
5747       end;
5748 
5749     SB_PAGEUP:
5750       begin
5751         UpdateScrollInfoFromSmoothPos(Info, Info.SmoothPos-Info.SmoothPage);
5752       end;
5753 
5754     SB_PAGEDOWN:
5755       begin
5756         UpdateScrollInfoFromSmoothPos(Info, Info.SmoothPos+Info.SmoothPage);
5757       end;
5758 
5759     SB_THUMBPOSITION:
5760       begin
5761         //must ignore message with Msg.Msg set: LM_VSCROLL, LM_HSCROLL;
5762         //we get it on macOS during window resize, not expected! moves v-scroll pos to 0.
5763         if Msg.Msg=0 then
5764           UpdateScrollInfoFromSmoothPos(Info, Msg.Pos);
5765       end;
5766 
5767     SB_THUMBTRACK:
5768       begin
5769         UpdateScrollInfoFromSmoothPos(Info, Msg.Pos);
5770         if Info.Vertical then
5771           DoHintShow;
5772       end;
5773 
5774     SB_ENDSCROLL:
5775       DoHintHide;
5776   end;
5777 
5778   //correct value (if -1)
5779   if Info.SmoothPos>Info.SmoothPosLast then
5780     UpdateScrollInfoFromSmoothPos(Info, Info.SmoothPosLast)
5781   else
5782   if Info.SmoothPos<0 then
5783     UpdateScrollInfoFromSmoothPos(Info, 0);
5784 
5785   Result:= Msg.ScrollCode<>SB_THUMBTRACK;
5786 end;
5787 
5788 procedure TATSynEdit.WMVScroll(var Msg: TLMVScroll);
5789 begin
5790   UpdateScrollInfoFromMessage(FScrollVert, Msg);
5791   Invalidate;
5792 end;
5793 
5794 {$ifdef windows}
5795 procedure TATSynEdit.WMIME_Request(var Msg: TMessage);
5796 begin
5797   if Assigned(FAdapterIME) then
5798     FAdapterIME.ImeRequest(Self, Msg);
5799 end;
5800 
5801 procedure TATSynEdit.WMIME_Notify(var Msg: TMessage);
5802 begin
5803   if Assigned(FAdapterIME) then
5804     FAdapterIME.ImeNotify(Self, Msg);
5805 end;
5806 
5807 procedure TATSynEdit.WMIME_StartComposition(var Msg: TMessage);
5808 begin
5809   if Assigned(FAdapterIME) then
5810     FAdapterIME.ImeStartComposition(Self, Msg);
5811 end;
5812 
5813 procedure TATSynEdit.WMIME_Composition(var Msg: TMessage);
5814 begin
5815   if Assigned(FAdapterIME) then
5816     FAdapterIME.ImeComposition(Self, Msg);
5817 end;
5818 
5819 procedure TATSynEdit.WMIME_EndComposition(var Msg: TMessage);
5820 begin
5821   if Assigned(FAdapterIME) then
5822     FAdapterIME.ImeEndComposition(Self, Msg);
5823 end;
5824 {$endif}
5825 
5826 procedure TATSynEdit.WMHScroll(var Msg: TLMHScroll);
5827 begin
5828   UpdateScrollInfoFromMessage(FScrollHorz, Msg);
5829   Invalidate;
5830 end;
5831 
5832 procedure TATSynEdit.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
5833 var
5834   PosTextClicked: TPoint;
5835   PosDetails: TATEditorPosDetails;
5836   Index: integer;
5837   ActionId: TATEditorMouseAction;
5838   bClickOnSelection: boolean;
5839   R: TRect;
5840 begin
5841   if not OptMouseEnableAll then exit;
5842   inherited;
5843   SetFocus;
5844   DoCaretForceShow;
5845 
5846   FMouseDownCoordOriginal.X:= X;
5847   FMouseDownCoordOriginal.Y:= Y;
5848   FMouseDownCoord.X:= X + FScrollHorz.TotalOffset;
5849   FMouseDownCoord.Y:= Y + FScrollVert.TotalOffset;
5850   FMouseDownWithCtrl:= ssXControl in Shift;
5851   FMouseDownWithAlt:= ssAlt in Shift;
5852   FMouseDownWithShift:= ssShift in Shift;
5853 
5854   if FMinimapVisible and PtInRect(FRectMinimap, Point(X, Y)) then
5855   begin
5856     GetRectMinimapSel(R);
5857     FMouseDownOnMinimap:= true;
5858     FMouseDragMinimapSelHeight:= R.Height;
5859     if FMinimapDragImmediately then
5860     begin
5861       FCursorOnMinimap:= true;
5862       FMouseDragMinimap:= true;
5863       FMouseDragMinimapDelta:= FMouseDragMinimapSelHeight div 2;
5864       FMouseDownOnMinimap:= false;
5865       DoMinimapDrag(Y);
5866     end
5867     else
5868     if PtInRect(R, Point(X, Y)) then
5869     begin
5870       FMouseDragMinimap:= true;
5871       FMouseDragMinimapDelta:= Y-R.Top;
5872     end;
5873     Exit;
5874   end;
5875 
5876   PosTextClicked:= ClientPosToCaretPos(Point(X, Y), PosDetails);
5877   FCaretSpecPos:= false;
5878   FMouseDownOnMinimap:= false;
5879   FMouseDownGutterLineNumber:= -1;
5880   FMouseDragDropping:= false;
5881   FMouseDragDroppingReal:= false;
5882   FMouseDragMinimap:= false;
5883   ActionId:= EditorMouseActionId(FMouseActions, Shift);
5884   bClickOnSelection:= false;
5885 
5886   ClearSelRectPoints; //SelRect points will be set in MouseMove
5887 
5888   if Assigned(FAdapterIME) then
5889     FAdapterIME.Stop(Self, false);
5890 
5891   if MouseNiceScroll then
5892   begin
5893     MouseNiceScroll:= false;
5894     Exit
5895   end;
5896 
5897   if PtInRect(FRectMain, Point(X, Y)) then
5898   begin
5899     FMouseDownPnt:= PosTextClicked;
5900     bClickOnSelection:= Carets.FindCaretContainingPos(FMouseDownPnt.X, FMouseDownPnt.Y)>=0;
5901 
5902     if Shift=[ssMiddle] then
5903       if DoHandleClickEvent(FOnClickMiddle) then Exit;
5904 
5905     //Ctrl+click on selection must not be ignored, but must start drag-drop with copying
5906     if ActionId=cMouseActionMakeCaret then
5907       if bClickOnSelection then
5908         ActionId:= cMouseActionClickSimple;
5909 
5910     if ActionId=cMouseActionClickMiddle then
5911     begin
5912       case FOptMouseMiddleClickAction of
5913         mcaScrolling:
5914           begin
5915             FMouseNiceScrollPos:= Point(X, Y);
5916             MouseNiceScroll:= true;
5917           end;
5918         mcaPaste:
5919           begin
5920             //don't set caret pos here, user needs to press middle-btn on any place to paste
5921             DoCommand(cCommand_ClipboardAltPaste, cInvokeInternal); //uses PrimarySelection:TClipboard
5922           end;
5923         mcaGotoDefinition:
5924           begin
5925             if cCommand_GotoDefinition>0 then
5926             begin
5927               DoCaretSingle(PosTextClicked.X, PosTextClicked.Y);
5928               DoCommand(cCommand_GotoDefinition, cInvokeInternal);
5929             end;
5930           end;
5931       end;
5932       Exit
5933     end;
5934 
5935     if ActionId=cMouseActionClickSimple then
5936     begin
5937       ActionAddJumpToUndo;
5938       Strings.SetGroupMark;
5939 
5940       FSelRect:= cRectEmpty;
5941       DoCaretSingleAsIs;
5942 
5943       if Assigned(PosDetails.OnGapItem) then
5944       begin
5945         if Assigned(FOnClickGap) then
5946           FOnClickGap(Self, PosDetails.OnGapItem, PosDetails.OnGapPos);
5947       end;
5948 
5949       if FOptMouseDragDrop and bClickOnSelection and not ModeReadOnly then
5950       begin
5951         //DragMode must be dmManual, drag started by code
5952         FMouseDragDropping:= true;
5953       end
5954       else
5955       begin
5956         if Assigned(FOnClickMoveCaret) then
5957           FOnClickMoveCaret(Self, Point(Carets[0].PosX, Carets[0].PosY), FMouseDownPnt);
5958 
5959         DoCaretSingle(FMouseDownPnt.X, FMouseDownPnt.Y);
5960         DoSelect_None;
5961       end;
5962     end;
5963 
5964     if ActionId=cMouseActionClickAndSelNormalBlock then
5965     begin
5966       FSelRect:= cRectEmpty;
5967       DoCaretSingleAsIs;
5968       Carets[0].SelectToPoint(FMouseDownPnt.X, FMouseDownPnt.Y);
5969     end;
5970 
5971     if ActionId=cMouseActionClickAndSelVerticalBlock then
5972     begin
5973       FSelRect:= cRectEmpty;
5974       DoCaretSingleAsIs;
5975       with Carets[0] do
5976         DoSelect_ColumnBlock_FromPoints(
5977           Point(PosX, PosY),
5978           FMouseDownPnt
5979           );
5980     end;
5981 
5982     if ActionId=cMouseActionMakeCaret then
5983     begin
5984       FSelRect:= cRectEmpty;
5985       DoCaretAddToPoint(FMouseDownPnt.X, FMouseDownPnt.Y);
5986     end;
5987 
5988     if ActionId=cMouseActionMakeCaretsColumn then
5989     begin
5990       FSelRect:= cRectEmpty;
5991       DoCaretsColumnToPoint(FMouseDownPnt.X, FMouseDownPnt.Y);
5992     end;
5993 
5994     if ActionId=cMouseActionClickRight then
5995     begin
5996       if FOptMouseRightClickMovesCaret then
5997         if not bClickOnSelection then //click over selection must never reset that selection, like in Notepad++
5998           if Strings.IsIndexValid(PosTextClicked.Y) then
5999           begin
6000             DoCaretSingle(PosTextClicked.X, PosTextClicked.Y);
6001             DoSelect_None;
6002             Invalidate;
6003            end;
6004     end;
6005   end;
6006 
6007   if FOptGutterVisible and PtInRect(FRectGutter, Point(X, Y)) then
6008   begin
6009     if ActionId=cMouseActionClickSimple then
6010     begin
6011       Index:= FGutter.IndexAt(X);
6012       if Index=FGutterBandNumbers then
6013       begin
6014         if FOptMouseClickNumberSelectsLine then
6015         begin
6016           FSelRect:= cRectEmpty;
6017           FMouseDownGutterLineNumber:= PosTextClicked.Y;
6018           DoSelect_Line(PosTextClicked);
6019         end;
6020       end
6021       else
6022       if Index=FGutterBandFolding then
6023       begin
6024         DoFoldbarClick(PosTextClicked.Y);
6025       end
6026       else
6027         //click on other bands- event
6028         DoEventClickGutter(FGutter.IndexAt(X), PosTextClicked.Y);
6029     end;
6030   end;
6031 
6032   if FMicromapVisible and not FMicromapOnScrollbar and PtInRect(FRectMicromap, Point(X, Y)) then
6033     if ActionId=cMouseActionClickSimple then
6034     begin
6035       DoEventClickMicromap(X-FRectMicromap.Left, Y-FRectMicromap.Top);
6036       Exit
6037     end;
6038 
6039   //don't fire OnChangeCaretPos on right click
6040   if Button=mbRight then
6041     if not FOptMouseRightClickMovesCaret then
6042       exit;
6043 
6044   Carets.Sort;
6045   DoEventCarets;
6046   Update;
6047 end;
6048 
6049 procedure TATSynEdit.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
6050 var
6051   bCopySelection: boolean;
6052   Str: atString;
6053   Caret: TATCaretItem;
6054   PosDetails: TATEditorPosDetails;
6055   PosTextClicked: TPoint;
6056 begin
6057   if not OptMouseEnableAll then exit;
6058   inherited;
6059 
6060   if FOptShowMouseSelFrame then
6061     if FMouseDragCoord.X>=0 then
6062     begin
6063       FMouseDragCoord:= Point(-1, -1);
6064       Invalidate;
6065     end;
6066 
6067   if PtInRect(FRectMinimap, Point(X, Y)) then
6068   begin
6069     if FMouseDownOnMinimap then
6070     begin
6071       FMouseDownOnMinimap:= false;
6072       if not FMouseDragMinimap then
6073         DoMinimapClick(Y);
6074       FMouseDragMinimap:= false;
6075     end;
6076     Exit
6077   end;
6078 
6079   if PtInRect(ClientRect, Point(X, Y)) then
6080   if FMouseDragDropping then
6081   begin
6082     //drag-drop really started
6083     if FMouseDragDroppingReal then
6084     begin
6085       Strings.BeginUndoGroup;
6086       try
6087         bCopySelection:=
6088           FOptMouseDragDropCopying and
6089           (FOptMouseDragDropCopyingWithState in Shift);
6090         DoDropText(not bCopySelection);
6091       finally
6092         Strings.EndUndoGroup;
6093         Update;
6094       end;
6095     end
6096     else
6097     //mouse released w/o drag-drop
6098     begin
6099       PosTextClicked:= ClientPosToCaretPos(Point(X, Y), PosDetails);
6100       DoCaretSingle(PosTextClicked.X, PosTextClicked.Y);
6101       DoEventCarets;
6102       Update;
6103     end;
6104     FMouseDragDropping:= false;
6105     FMouseDragDroppingReal:= false;
6106   end;
6107 
6108   if FOptMouseClickOpensURL then
6109     if not FMouseDownDouble and not FMouseDragDropping and (Button=mbLeft) then
6110       if Carets.Count=1 then
6111       begin
6112         Caret:= Carets[0];
6113         Str:= DoGetLinkAtPos(Caret.PosX, Caret.PosY);
6114         if Str<>'' then
6115           if Assigned(FOnClickLink) then
6116             FOnClickLink(Self, Str);
6117       end;
6118 
6119   ClearMouseDownVariables;
6120 
6121   if Carets.Count=1 then
6122     with Carets[0] do
6123     begin
6124       //mouse-up after selection made
6125       if EndY>=0 then
6126       begin
6127         if Assigned(FOnClickEndSelect) then
6128           FOnClickEndSelect(Self, Point(EndX, EndY), Point(PosX, PosY));
6129       end
6130       //else: simple mouse click
6131     end;
6132 end;
6133 
6134 procedure TATSynEdit.ClearSelRectPoints;
6135 begin
6136   FLastCommandMakesColumnSel:= false;
6137   FSelRectBegin:= Point(-1, -1);
6138   FSelRectEnd:= Point(-1, -1);
6139 end;
6140 
6141 procedure TATSynEdit.ClearMouseDownVariables;
6142 begin
6143   FMouseDownCoordOriginal:= Point(-1, -1);
6144   FMouseDownCoord:= Point(-1, -1);
6145   FMouseDownPnt:= Point(-1, -1);
6146   FMouseDownGutterLineNumber:= -1;
6147   FMouseDownDouble:= false;
6148   FMouseDownAndColumnSelection:= false;
6149   FMouseDownOnMinimap:= false;
6150   FMouseDownWithCtrl:= false;
6151   FMouseDownWithAlt:= false;
6152   FMouseDownWithShift:= false;
6153   FMouseDragDropping:= false;
6154   FMouseDragDroppingReal:= false;
6155   FMouseDragMinimap:= false;
6156   FTimerScroll.Enabled:= false;
6157 end;
6158 
6159 procedure TATSynEdit.DoHandleRightClick(X, Y: integer);
6160 var
6161   Index: integer;
6162 begin
6163   if PtInRect(FRectMain, Point(X, Y)) then
6164   begin
6165     if Assigned(FMenuText) then
6166       FMenuText.PopUp
6167     else
6168     begin
6169       InitMenuStd;
6170       FMenuStd.PopUp;
6171     end;
6172   end
6173   else
6174   if FOptGutterVisible and PtInRect(FRectGutter, Point(X, Y)) then
6175   begin
6176     Index:= FGutter.IndexAt(X);
6177     if Index=FGutterBandBookmarks then
6178       if Assigned(FMenuGutterBm) then FMenuGutterBm.PopUp;
6179     if Index=FGutterBandNumbers then
6180       if Assigned(FMenuGutterNum) then FMenuGutterNum.PopUp;
6181     if Index=FGutterBandFolding then
6182       if Assigned(FMenuGutterFold) then FMenuGutterFold.PopUp else DoMenuGutterFold;
6183   end
6184   else
6185   if FMinimapVisible and PtInRect(FRectMinimap, Point(X, Y)) then
6186   begin
6187     if Assigned(FMenuMinimap) then FMenuMinimap.PopUp;
6188   end
6189   else
6190   if FMicromapVisible and not FMicromapOnScrollbar and PtInRect(FRectMicromap, Point(X, Y)) then
6191   begin
6192     if Assigned(FMenuMicromap) then FMenuMicromap.PopUp;
6193   end
6194   else
6195   if FOptRulerVisible and PtInRect(FRectRuler, Point(X, Y)) then
6196   begin
6197     if Assigned(FMenuRuler) then FMenuRuler.PopUp;
6198   end;
6199 end;
6200 
6201 procedure TATSynEdit.UpdateCursor;
6202 var
6203   P: TPoint;
6204   RectBm, RectNums: TRect;
6205 begin
6206   if MouseNiceScroll then Exit;
6207   P:= ScreenToClient(Mouse.CursorPos);
6208 
6209   RectBm.Left:= FGutter[FGutterBandBookmarks].Left;
6210   RectBm.Right:= FGutter[FGutterBandBookmarks].Right;
6211   RectBm.Top:= FRectGutter.Top;
6212   RectBm.Bottom:= FRectGutter.Bottom;
6213 
6214   RectNums.Left:= FGutter[FGutterBandNumbers].Left;
6215   RectNums.Right:= FGutter[FGutterBandNumbers].Right;
6216   RectNums.Top:= FRectGutter.Top;
6217   RectNums.Bottom:= FRectGutter.Bottom;
6218 
6219   //if FMouseDragDropping then
6220   //  Cursor:= crDrag
6221   //else
6222   //if FMouseDragMinimap then
6223   //  Cursor:= crSizeNS
6224   //else
6225   if PtInRect(FRectMain, P) then
6226   begin
6227     if FMouseDragDropping and FMouseDragDroppingReal then
6228       Cursor:= crDrag
6229     else
6230     if FMouseDownAndColumnSelection then
6231       Cursor:= FCursorColumnSel
6232     else
6233       Cursor:= FCursorText;
6234   end
6235   else
6236   if PtInRect(RectBm, P) then
6237     Cursor:= FCursorGutterBookmark
6238   else
6239   if PtInRect(RectNums, P) then
6240     Cursor:= FCursorGutterNumbers
6241   else
6242   if PtInRect(FRectMinimap, P) then
6243     Cursor:= FCursorMinimap
6244   else
6245   if PtInRect(FRectMicromap, P) then
6246     Cursor:= FCursorMicromap
6247   else
6248     Cursor:= crDefault;
6249 end;
6250 
6251 
6252 procedure _LimitPointByRect(var P: TPoint; const R: TRect); inline;
6253 begin
6254   if P.X<R.Left+1 then P.X:= R.Left+1;
6255   if P.X>R.Right then P.X:= R.Right;
6256   if P.Y<R.Top+1 then P.Y:= R.Top+1;
6257   if P.Y>R.Bottom then P.Y:= R.Bottom;
6258 end;
6259 
6260 procedure TATSynEdit.MouseMove(Shift: TShiftState; X, Y: Integer);
6261 const
6262   cMovedDeltaPx = 5;
6263 var
6264   P: TPoint;
6265   RectNums, RectBookmk: TRect;
6266   bOnMain, bOnMinimap, bOnMicromap,
6267   bOnGutter, bOnGutterNumbers, bOnGutterBookmk,
6268   bSelecting, bSelectingGutterNumbers: boolean;
6269   bMovedMinimal: boolean;
6270   bUpdateForMinimap: boolean;
6271   Details: TATEditorPosDetails;
6272   nIndex: integer;
6273   Caret: TATCaretItem;
6274 begin
6275   if not OptMouseEnableAll then exit;
6276   inherited;
6277 
6278   P:= Point(X, Y);
6279   UpdateCursor;
6280 
6281   bMovedMinimal:= IsPointsDiffByDelta(P, FMouseDownCoordOriginal, cMovedDeltaPx);
6282 
6283   bSelecting:= (not FMouseDragDropping) and (FMouseDownPnt.X>=0);
6284   bSelectingGutterNumbers:= FMouseDownGutterLineNumber>=0;
6285 
6286   if bSelecting then
6287   begin
6288     FMouseDragCoord:= P;
6289     _LimitPointByRect(FMouseDragCoord, FRectMainVisible);
6290   end
6291   else
6292     FMouseDragCoord:= Point(-1, -1);
6293 
6294   bOnMain:= PtInRect(FRectMain, P);
6295   bOnMinimap:= FMinimapVisible and PtInRect(FRectMinimap, P);
6296   bOnMicromap:= FMicromapVisible and not FMicromapOnScrollbar and PtInRect(FRectMicromap, P);
6297   bOnGutter:= FOptGutterVisible and PtInRect(FRectGutter, P);
6298   bOnGutterNumbers:= false;
6299   bOnGutterBookmk:= false;
6300 
6301   //detect cursor on minimap
6302   if FMinimapVisible then
6303   begin
6304     bUpdateForMinimap:= false;
6305     if bOnMinimap<>FCursorOnMinimap then
6306       bUpdateForMinimap:= true;
6307     FCursorOnMinimap:= bOnMinimap;
6308     if FMinimapTooltipVisible and bOnMinimap then
6309     begin
6310       FMinimapTooltipEnabled:= true;
6311       bUpdateForMinimap:= true;
6312     end
6313     else
6314       FMinimapTooltipEnabled:= false;
6315     if bUpdateForMinimap then
6316       Update;
6317 
6318     //mouse dragged on minimap
6319     //handle this before starting FTimerScroll (CudaText issues 2941, 2944)
6320     if FMouseDragMinimap then
6321     begin
6322       if bMovedMinimal then
6323         if Shift=[ssLeft] then
6324           DoMinimapDrag(Y);
6325       Exit
6326       end;
6327   end;
6328 
6329   //detect cursor on gutter
6330   if FOptGutterVisible then
6331   begin
6332     if not FOptGutterShowFoldAlways then
6333       if bOnGutter<>FCursorOnGutter then
6334         Invalidate;
6335     FCursorOnGutter:= bOnGutter;
6336   end;
6337 
6338   RectNums:= Rect(0, 0, 0, 0);
6339   RectBookmk:= Rect(0, 0, 0, 0);
6340   if FOptGutterVisible then
6341   begin
6342     if FGutter[FGutterBandNumbers].Visible then
6343     begin
6344       RectNums.Left:= FGutter[FGutterBandNumbers].Left;
6345       RectNums.Right:= FGutter[FGutterBandNumbers].Right;
6346       RectNums.Top:= FRectMain.Top;
6347       RectNums.Bottom:= FRectMain.Bottom;
6348 
6349       bOnGutterNumbers:= bOnGutter and PtInRect(RectNums, P);
6350     end;
6351 
6352     if FGutter[FGutterBandBookmarks].Visible then
6353     begin
6354       RectBookmk.Left:= FGutter[FGutterBandBookmarks].Left;
6355       RectBookmk.Right:= FGutter[FGutterBandBookmarks].Right;
6356       RectBookmk.Top:= FRectMain.Top;
6357       RectBookmk.Bottom:= FRectMain.Bottom;
6358 
6359       bOnGutterBookmk:= bOnGutter and PtInRect(RectBookmk, P);
6360     end;
6361   end;
6362 
6363   //detect cursor on folded marks
6364   if FFoldTooltipVisible and Assigned(FFoldedMarkList) then
6365   begin
6366     FFoldedMarkCurrent:= FFoldedMarkList.FindByCoord(Point(X, Y));
6367     UpdateFoldedMarkTooltip;
6368   end;
6369 
6370   //show/hide bookmark hint
6371   if bOnGutterBookmk and not bSelecting then
6372   begin
6373     P:= ClientPosToCaretPos(Point(X, Y), Details);
6374     DoHintShowForBookmark(P.Y);
6375   end
6376   else
6377     DoHintHide;
6378 
6379   //start scroll timer
6380   FTimerScroll.Enabled:=
6381     FOptMouseEnableAll and
6382     FOptMouseEnableNormalSelection and
6383     FOptMouseEnableColumnSelection and
6384     (ssLeft in Shift) and
6385     (not bOnMain) and
6386     //auto-scroll must not work when cursor is over minimap/micromap
6387     (not bOnMinimap) and
6388     (not bOnMicromap) and
6389     (not bOnGutter);
6390 
6391   FMouseAutoScroll:= cDirNone;
6392   if (P.Y<FRectMain.Top) and (not ModeOneLine) then
6393     FMouseAutoScroll:= cDirUp else
6394   if (P.Y>=FRectMain.Bottom) and (not ModeOneLine) then
6395     FMouseAutoScroll:= cDirDown else
6396   if (P.X<FRectMain.Left) then
6397     FMouseAutoScroll:= cDirLeft else
6398   if (P.X>=FRectMain.Right) then
6399     FMouseAutoScroll:= cDirRight;
6400 
6401   //mouse dragged on gutter numbers (only if drag started on gutter numbers)
6402   if bSelectingGutterNumbers then
6403     if bOnGutterNumbers then
6404     begin
6405       if Shift=[ssLeft] then
6406       begin
6407         P:= ClientPosToCaretPos(P, Details);
6408         if (P.Y>=0) and (P.X>=0) then
6409         begin
6410           DoSelect_LineRange(FMouseDownGutterLineNumber, P);
6411           Carets.Sort;
6412           DoEventCarets;
6413           Invalidate;
6414         end;
6415       end;
6416     Exit
6417   end;
6418 
6419   //mouse drag-drop just begins
6420   if bOnMain and FMouseDragDropping then
6421   begin
6422     if not FMouseDragDroppingReal and
6423       IsPointsDiffByDelta(Point(X, Y), FMouseDownCoordOriginal, Mouse.DragThreshold) then
6424     begin
6425       FMouseDragDroppingReal:= true;
6426       BeginDrag(true);
6427     end
6428     else
6429       Invalidate; //Invalidate is needed even if nothing changed, just to paint drop-marker
6430     exit;
6431   end;
6432 
6433   //mouse just moved on text
6434   if bOnMain and (FMouseDownPnt.X<0) then
6435     begin
6436       if Shift*[ssLeft, ssRight]=[] then
6437         if Assigned(FHotspots) and (FHotspots.Count>0) then
6438         begin
6439           P:= ClientPosToCaretPos(P, Details);
6440           if P.Y>=0 then
6441           begin
6442             nIndex:= FHotspots.FindByPos(P.X, P.Y);
6443             if nIndex<>FLastHotspot then
6444             begin
6445               if FLastHotspot>=0 then
6446                 if Assigned(FOnHotspotExit) then
6447                   FOnHotspotExit(Self, FLastHotspot);
6448 
6449               if nIndex>=0 then
6450                 if Assigned(FOnHotspotEnter) then
6451                   FOnHotspotEnter(Self, nIndex);
6452 
6453               FLastHotspot:= nIndex;
6454             end;
6455           end;
6456         end;
6457       Exit
6458     end;
6459 
6460   //mouse dragged to select block
6461   if bSelecting then
6462     if bOnMain or bOnGutter then
6463     begin
6464       if ssLeft in Shift then
6465         if Carets.Count>0 then
6466         begin
6467           P:= ClientPosToCaretPos(P, Details);
6468           //Application.MainForm.Caption:= Format('MouseDownPnt %d:%d, CurPnt %d:%d',
6469             //[FMouseDownPnt.Y, FMouseDownPnt.X, P.Y, P.X]);
6470           if (P.Y<0) then Exit;
6471 
6472           //mouse not moved at last by char?
6473           if (FMouseDownPnt.X=P.X) and (FMouseDownPnt.Y=P.Y) then
6474           begin
6475             //remove selection from current caret
6476             nIndex:= Carets.IndexOfPosXY(FMouseDownPnt.X, FMouseDownPnt.Y, true);
6477             if Carets.IsIndexValid(nIndex) then
6478             begin
6479               Caret:= Carets[nIndex];
6480               Caret.PosX:= P.X;
6481               Caret.PosY:= P.Y;
6482               Caret.EndX:= -1;
6483               Caret.EndY:= -1;
6484             end;
6485             Invalidate;
6486           end
6487           else
6488           begin
6489             //drag w/out button pressed: single selection
6490             //ssShift is allowed to select by Shift+MouseWheel
6491             if not FMouseDownWithCtrl and not FMouseDownWithAlt then
6492             begin
6493               if FOptMouseEnableColumnSelection and FOptMouseColumnSelectionWithoutKey then
6494               begin
6495                 //column selection
6496                 FMouseDownAndColumnSelection:= true;
6497                 DoCaretSingle(FMouseDownPnt.X, FMouseDownPnt.Y);
6498                 DoSelect_None;
6499                 DoSelect_ColumnBlock_FromPoints(FMouseDownPnt, P);
6500               end
6501               else
6502               if FOptMouseEnableNormalSelection then
6503               begin
6504                 //normal selection
6505                 DoCaretSingleAsIs;
6506                 if FMouseDownDouble and FOptMouse2ClickDragSelectsWords then
6507                   DoSelect_WordRange(0, FMouseDownPnt, P)
6508                 else
6509                   DoSelect_CharRange(0, P);
6510               end;
6511             end;
6512 
6513             //drag with Ctrl pressed: add selection
6514             if (ssLeft in Shift) and
6515               FMouseDownWithCtrl and
6516               not FMouseDownWithAlt and
6517               not FMouseDownWithShift then
6518             begin
6519               nIndex:= Carets.IndexOfPosXY(FMouseDownPnt.X, FMouseDownPnt.Y, true);
6520               DoSelect_CharRange(nIndex, P);
6521             end;
6522 
6523             //drag with Alt pressed: column selection
6524             if FOptMouseEnableColumnSelection then
6525               if (ssLeft in Shift) and
6526                 not FMouseDownWithCtrl and
6527                 FMouseDownWithAlt and
6528                 not FMouseDownWithShift then
6529               begin
6530                 FMouseDownAndColumnSelection:= true;
6531                 DoCaretSingle(FMouseDownPnt.X, FMouseDownPnt.Y);
6532                 DoSelect_None;
6533                 DoSelect_ColumnBlock_FromPoints(FMouseDownPnt, P);
6534               end;
6535 
6536             Carets.Sort;
6537             DoEventCarets;
6538             Invalidate;
6539           end;
6540         end;
6541       Exit;
6542     end;
6543 end;
6544 
6545 procedure TATSynEdit.MouseLeave;
6546 begin
6547   if not OptMouseEnableAll then exit;
6548   inherited;
6549   DoHideAllTooltips;
6550 end;
6551 
DoMouseWheelnull6552 function TATSynEdit.DoMouseWheel(Shift: TShiftState; WheelDelta: integer;
6553   MousePos: TPoint): boolean;
6554 begin
6555   if not OptMouseEnableAll then exit(false);
6556 
6557   Result:= DoMouseWheelAction(Shift, WheelDelta, false)
6558 end;
6559 
DoMouseWheelHorznull6560 function TATSynEdit.DoMouseWheelHorz(Shift: TShiftState; WheelDelta: integer;
6561   MousePos: TPoint): boolean;
6562 begin
6563   if not OptMouseEnableAll then exit(false);
6564 
6565   Result:= DoMouseWheelAction([], -WheelDelta, true);
6566 end;
6567 
6568 type
6569   TATMouseWheelMode = (
6570     aWheelModeNormal,
6571     aWheelModeHoriz,
6572     aWheelModeZoom
6573     );
6574 
6575 procedure TATSynEdit.DoHideAllTooltips;
6576 var
6577   bUpdate: boolean;
6578 begin
6579   bUpdate:= FMinimapTooltipEnabled;
6580 
6581   DoHintHide;
6582   DoHotspotsExit;
6583   if Assigned(FFoldedMarkTooltip) then
6584     FFoldedMarkTooltip.Hide;
6585   FMinimapTooltipEnabled:= false;
6586 
6587   if bUpdate then
6588     Update;
6589 end;
6590 
DoMouseWheelActionnull6591 function TATSynEdit.DoMouseWheelAction(Shift: TShiftState;
6592   AWheelDelta: integer; AForceHorz: boolean): boolean;
6593 var
6594   WheelRecord: TATEditorWheelRecord;
6595   Mode: TATMouseWheelMode;
6596   Pnt: TPoint;
6597 begin
6598   Result:= false;
6599   if not OptMouseEnableAll then exit;
6600   if ModeOneLine then exit;
6601   DoHideAllTooltips;
6602 
6603   if AForceHorz then
6604     Mode:= aWheelModeHoriz
6605   else
6606   if (Shift=[FOptMouseWheelZoomsWithState]) then
6607     Mode:= aWheelModeZoom
6608   else
6609   // -[ssLeft] to ignore pressed mouse button
6610   if (Shift-[ssLeft]=[FOptMouseWheelScrollHorzWithState]) then
6611     Mode:= aWheelModeHoriz
6612   else
6613   // -[ssLeft] to ignore pressed mouse button
6614   if (Shift-[ssLeft]=[]) then
6615     Mode:= aWheelModeNormal
6616   else
6617     exit;
6618 
6619   WheelRecord:= Default(TATEditorWheelRecord);
6620 
6621   case Mode of
6622     aWheelModeNormal:
6623       begin
6624         if FOptMouseWheelScrollVert then
6625         begin
6626           WheelRecord.Kind:= wqkVert;
6627           WheelRecord.Delta:= AWheelDelta;
6628           //FWheelQueue.Push(WheelRecord);
6629           DoHandleWheelRecord(WheelRecord);
6630           Update;
6631 
6632           Result:= true;
6633         end;
6634       end;
6635 
6636     aWheelModeHoriz:
6637       begin
6638         if FOptMouseWheelScrollHorz then
6639         begin
6640           WheelRecord.Kind:= wqkHorz;
6641           WheelRecord.Delta:= AWheelDelta;
6642           //FWheelQueue.Push(WheelRecord);
6643           DoHandleWheelRecord(WheelRecord);
6644           Update;
6645 
6646           Result:= true;
6647         end;
6648       end;
6649 
6650     aWheelModeZoom:
6651       begin
6652         if FOptMouseWheelZooms then
6653         begin
6654           WheelRecord.Kind:= wqkZoom;
6655           WheelRecord.Delta:= AWheelDelta;
6656           //FWheelQueue.Push(WheelRecord);
6657           DoHandleWheelRecord(WheelRecord);
6658           Update;
6659 
6660           Result:= true;
6661         end;
6662       end;
6663   end;
6664 
6665   if ssLeft in Shift then
6666   begin
6667     Pnt:= ScreenToClient(Mouse.CursorPos);
6668     MouseMove(Shift, Pnt.X, Pnt.Y);
6669   end;
6670 end;
6671 
DoHandleClickEventnull6672 function TATSynEdit.DoHandleClickEvent(AEvent: TATSynEditClickEvent): boolean;
6673 begin
6674   Result:= false;
6675   if Assigned(AEvent) then
6676     AEvent(Self, Result);
6677 end;
6678 
6679 procedure TATSynEdit.DblClick;
6680 var
6681   Caret: TATCaretItem;
6682   SLink: atString;
6683 begin
6684   if not OptMouseEnableAll then exit;
6685   inherited;
6686 
6687   if DoHandleClickEvent(FOnClickDbl) then Exit;
6688 
6689   if FOptMouse2ClickOpensURL then
6690     if Carets.Count>0 then
6691     begin
6692       Caret:= Carets[0];
6693       SLink:= DoGetLinkAtPos(Caret.PosX, Caret.PosY);
6694       if SLink<>'' then
6695       begin
6696         if Assigned(FOnClickLink) then
6697           FOnClickLink(Self, SLink);
6698         DoEventCarets;
6699         exit
6700       end;
6701     end;
6702 
6703   case FOptMouse2ClickAction of
6704     cMouseDblClickSelectEntireLine:
6705       begin
6706         DoSelect_Line_ByClick;
6707       end;
6708     cMouseDblClickSelectWordChars:
6709       begin
6710         FMouseDownDouble:= true;
6711         DoSelect_ByDoubleClick(true);
6712       end;
6713     cMouseDblClickSelectAnyChars:
6714       begin
6715         FMouseDownDouble:= true;
6716         DoSelect_ByDoubleClick(false);
6717       end;
6718   end;
6719 
6720   DoEventCarets;
6721 end;
6722 
6723 procedure TATSynEdit.TripleClick;
6724 begin
6725   if not OptMouseEnableAll then exit;
6726   inherited;
6727 
6728   if DoHandleClickEvent(FOnClickTriple) then Exit;
6729 
6730   if FOptMouse3ClickSelectsLine then
6731     DoSelect_Line_ByClick;
6732 end;
6733 
6734 
6735 procedure TATSynEdit.DoSelect_ByDoubleClick(AllowOnlyWordChars: boolean);
6736 begin
6737   if not Strings.IsIndexValid(FMouseDownPnt.Y) then Exit;
6738   DoSelect_CharGroupAtPos(FMouseDownPnt, EditorIsPressedCtrl, AllowOnlyWordChars);
6739   Invalidate;
6740 end;
6741 
GetCaretManyAllowednull6742 function TATSynEdit.GetCaretManyAllowed: boolean;
6743 begin
6744   Result:= Carets.ManyAllowed;
6745 end;
6746 
6747 procedure TATSynEdit.SetCaretManyAllowed(AValue: boolean);
6748 begin
6749   Carets.ManyAllowed:= AValue;
6750   if not AValue then
6751     DoCaretSingleAsIs;
6752 end;
6753 
6754 
6755 procedure TATSynEdit.DoSelect_Line_ByClick;
6756 var
6757   P: TPoint;
6758   Details: TATEditorPosDetails;
6759 begin
6760   P:= ScreenToClient(Mouse.CursorPos);
6761   if PtInRect(FRectMain, P) then
6762   begin
6763     P:= ClientPosToCaretPos(P, Details);
6764     if P.Y<0 then Exit;
6765     DoSelect_Line(P);
6766     Invalidate;
6767   end;
6768 end;
6769 
IsInvalidateAllowednull6770 function TATSynEdit.IsInvalidateAllowed: boolean;
6771 begin
6772   exit(true);
6773 
6774   {
6775   //solve CudaText issue #3461
6776   //but this gives random hangings on editing, e.g. CudaText #3475, also AT sees hangings on macOS
6777   if Assigned(AdapterForHilite) then
6778     Result:= AdapterForHilite.IsParsedAtLeastPartially
6779   else
6780     Result:= true;
6781     }
6782 
6783   { //debug
6784   if not Result then
6785     if Assigned(Application) and Assigned(Application.MainForm) then
6786       Application.MainForm.Caption:= 'skip invalidate: '+TimeToStr(Now)+', lexer: '+AdapterForHilite.GetLexerName;
6787     }
6788 end;
6789 
6790 procedure TATSynEdit.Invalidate;
6791 begin
6792   if not IsRepaintEnabled then exit;
6793   //if not IsInvalidateAllowed then exit;
6794 
6795   if ATEditorOptions.FlickerReducingPause>=1000 then
6796   begin
6797     if Assigned(AdapterForHilite) then
6798       if not AdapterForHilite.IsDataReadyPartially then exit;
6799   end
6800   else
6801   if ATEditorOptions.FlickerReducingPause>0 then
6802   begin
6803     FTimerFlicker.Enabled:= false;
6804     FTimerFlicker.Interval:= ATEditorOptions.FlickerReducingPause;
6805     FTimerFlicker.Enabled:= true;
6806     exit;
6807   end;
6808 
6809   Include(FPaintFlags, cIntFlagBitmap);
6810   inherited;
6811 
6812   if cIntFlagScrolled in FPaintFlags then
6813   begin
6814     Exclude(FPaintFlags, cIntFlagScrolled);
6815     DoEventScroll;
6816   end;
6817 end;
6818 
_IsFocusednull6819 function TATSynEdit._IsFocused: boolean;
6820 //this method is to speedup focused check (TControl.Focused prop is slower)
6821 var
6822   C: TControl;
6823 begin
6824   Result:= false;
6825   if not FIsEntered then exit;
6826   if not Application.Active then exit;
6827 
6828   C:= Self;
6829   while Assigned(C.Parent) do
6830     C:= C.Parent;
6831   if C is TForm then
6832     if not (C as TForm).Active then exit;
6833 
6834   Result:= true;
6835 end;
6836 
6837 procedure TATSynEdit.TimerBlinkTick(Sender: TObject);
6838 begin
6839   if not FCaretShowEnabled then exit;
6840 
6841   if FCaretStopUnfocused and not _IsFocused then
6842     if FCaretShown then
6843       exit;
6844 
6845   if not DoubleBuffered then
6846     FCaretAllowNextBlink:= not FCaretAllowNextBlink;
6847 
6848   DoPaintCarets(Canvas, true);
6849 end;
6850 
6851 procedure TATSynEdit.TimerScrollTick(Sender: TObject);
6852 var
6853   nIndex: integer;
6854   PClient, PCaret: TPoint;
6855   Details: TATEditorPosDetails;
6856 begin
6857   PClient:= ScreenToClient(Mouse.CursorPos);
6858   PClient.X:= Max(FRectMain.Left, PClient.X);
6859   PClient.Y:= Max(FRectMain.Top, PClient.Y);
6860   PClient.X:= Min(FRectMain.Right, PClient.X);
6861   PClient.Y:= Min(FRectMain.Bottom, PClient.Y);
6862 
6863   case FMouseAutoScroll of
6864     cDirUp:
6865       DoScrollByDelta(0, -ATEditorOptions.SpeedScrollAutoVert);
6866     cDirDown:
6867       DoScrollByDelta(0, ATEditorOptions.SpeedScrollAutoVert);
6868     cDirLeft:
6869       DoScrollByDelta(-ATEditorOptions.SpeedScrollAutoHorz, 0);
6870     cDirRight:
6871       DoScrollByDelta(ATEditorOptions.SpeedScrollAutoHorz, 0);
6872     else
6873       Exit;
6874   end;
6875 
6876   PCaret:= ClientPosToCaretPos(PClient, Details);
6877 
6878   if (PCaret.X>=0) and (PCaret.Y>=0) then
6879   begin
6880     if FMouseDownGutterLineNumber>=0 then
6881     begin
6882       DoSelect_LineRange(FMouseDownGutterLineNumber, PCaret);
6883     end
6884     else
6885     if IsSelRectEmpty then
6886     begin
6887       nIndex:= Carets.IndexOfPosXY(FMouseDownPnt.X, FMouseDownPnt.Y, true);
6888       if nIndex>=0 then
6889         Carets[nIndex].SelectToPoint(PCaret.X, PCaret.Y);
6890     end
6891     else
6892     begin
6893       DoSelect_ColumnBlock_FromPoints(FMouseDownPnt, PCaret);
6894     end;
6895   end;
6896 
6897   Carets.Sort;
6898   DoEventCarets;
6899   Invalidate;
6900 end;
6901 
6902 procedure TATSynEdit.TimerNiceScrollTick(Sender: TObject);
6903 var
6904   Pnt: TPoint;
6905   Dx, Dy: integer;
6906   Dir: TATEditorDirection;
6907 begin
6908   Pnt:= ScreenToClient(Mouse.CursorPos);
6909   if not PtInRect(FRectMain, Pnt) then Exit;
6910 
6911   //delta in pixels
6912   Dx:= Pnt.X-FMouseNiceScrollPos.X;
6913   Dy:= Pnt.Y-FMouseNiceScrollPos.Y;
6914 
6915   if (Abs(Dx)<=cBitmapNiceScroll.Height div 2) and
6916     (Abs(Dy)<=cBitmapNiceScroll.Height div 2) then
6917     begin
6918       Cursor:= crNiceScrollNone;
6919       Exit;
6920     end;
6921 
6922   if (Dy<0) and (Abs(Dy)>Abs(Dx)) then Dir:= cDirUp else
6923     if (Dy>0) and (Abs(Dy)>Abs(Dx)) then Dir:= cDirDown else
6924       if Dx<0 then Dir:= cDirLeft else
6925         Dir:= cDirRight;
6926 
6927   case Dir of
6928     cDirLeft:  Cursor:= crNiceScrollLeft;
6929     cDirRight: Cursor:= crNiceScrollRight;
6930     cDirUp:    Cursor:= crNiceScrollUp;
6931     cDirDown:  Cursor:= crNiceScrollDown;
6932   end;
6933 
6934   //delta in pixels
6935   Dx:= Sign(Dx)*((Abs(Dx)-cBitmapNiceScroll.Height div 2) + 1) div cSpeedScrollNice;
6936   Dy:= Sign(Dy)*((Abs(Dy)-cBitmapNiceScroll.Height div 2) + 1) div cSpeedScrollNice;
6937 
6938   if Dir in [cDirLeft, cDirRight] then
6939     DoScrollByDeltaInPixels(Dx, 0)
6940   else
6941     DoScrollByDeltaInPixels(0, Dy);
6942 
6943   Invalidate;
6944 end;
6945 
6946 
6947 procedure TATSynEdit.DoPaintCarets(C: TCanvas; AWithInvalidate: boolean);
6948 var
6949   Caret: TATCaretItem;
6950   CaretShape: TATCaretShape;
6951   NCaretColor: TColor;
6952   R: TRect;
6953   //
6954   procedure DoPaintCaretShape;
6955   var
6956     NCoordX, NCoordY: integer;
6957   begin
6958     CanvasInvertRect(C, R, NCaretColor);
6959 
6960     if CaretShape.EmptyInside then
6961       CanvasInvertRect(C, Rect(R.Left+1, R.Top+1, R.Right-1, R.Bottom-1), NCaretColor)
6962     else
6963     if ATEditorOptions.CaretTextOverInvertedRect then
6964     begin
6965       if (Caret.CharStr<>'') and (Caret.CharColor<>clNone) and not IsCharUnicodeSpace(Caret.CharStr[1]) then
6966       begin
6967         C.Font.Color:= Caret.CharColor;
6968         C.Font.Style:= Caret.CharStyles;
6969         C.Brush.Style:= bsClear;
6970         NCoordX:= Caret.CoordX;
6971         NCoordY:= Caret.CoordY;
6972         if OptSpacingY<0 then
6973           Inc(NCoordY, OptSpacingY);
6974         CanvasTextOutSimplest(C, NCoordX, NCoordY, Caret.CharStr);
6975       end;
6976     end;
6977   end;
6978   //
6979 var
6980   NCharWidth: integer;
6981   i: integer;
6982 begin
6983   if csLoading in ComponentState then exit;
6984   if csDestroying in ComponentState then exit;
6985   if not FCaretShowEnabled then exit;
6986 
6987   //disable InvalidateRect during Paint
6988   if (csCustomPaint in ControlState) then
6989     AWithInvalidate:= false;
6990   if not IsInvalidateAllowed then
6991     AWithInvalidate:= false;
6992 
6993   if ModeReadOnly then
6994     CaretShape:= FCaretShapeReadonly
6995   else
6996   if ModeOverwrite then
6997     CaretShape:= FCaretShapeOverwrite
6998   else
6999     CaretShape:= FCaretShapeNormal;
7000 
7001   NCaretColor:= Colors.Caret;
7002   { //block was needed when we didn't have OptCaretHideUnfocused
7003   if (not FCaretStopUnfocused) or _IsFocused then
7004     NCaretColor:= Colors.Caret
7005   else
7006     //I cannot find proper color of NCaretColor, to make unfocused carets invisible,
7007     //tried several combinations: Colors.TextBG with Colors.TextFont with 'xor'.
7008     //at least value 'Colors.TextBG xor Colors.TextFont' gives PALE caret color
7009     //on many CudaText themes (default and dark themes).
7010     NCaretColor:= Colors.TextBG xor Colors.TextFont;
7011     }
7012 
7013   if FCaretBlinkEnabled then
7014     FCaretShown:= not FCaretShown
7015   else
7016     FCaretShown:= true;
7017 
7018   NCharWidth:= FCharSize.XScaled div ATEditorCharXScale;
7019 
7020   for i:= 0 to FCarets.Count-1 do
7021   begin
7022     Caret:= FCarets[i];
7023     if Caret.CoordX=-1 then Continue;
7024     R.Left:= Caret.CoordX;
7025     R.Top:= Caret.CoordY;
7026     R.Right:= R.Left+NCharWidth;
7027     R.Bottom:= R.Top+FCharSize.Y;
7028 
7029     //check caret is visible (IntersectRect is slower)
7030     if R.Right<=FRectMain.Left then Continue;
7031     if R.Bottom<=FRectMain.Top then Continue;
7032     if R.Left>=FRectMain.Right then Continue;
7033     if R.Top>=FRectMain.Bottom then Continue;
7034 
7035     DoCaretsApplyShape(R, CaretShape, NCharWidth, FCharSize.Y);
7036 
7037     if FCaretBlinkEnabled then
7038     begin
7039       //this block is to solve 'ghost caret on typing'
7040       //CudaText issue #3167
7041       if not FCaretShown then
7042       begin
7043         if Caret.OldRect.Width>0 then
7044         begin
7045           CanvasInvertRect(C, Caret.OldRect, NCaretColor);
7046           if AWithInvalidate then
7047             InvalidateRect(Handle, @Caret.OldRect, false);
7048         end;
7049       end;
7050 
7051       DoPaintCaretShape;
7052     end
7053     else
7054     begin
7055       DoPaintCaretShape;
7056     end;
7057 
7058     Caret.OldRect:= R;
7059 
7060     if AWithInvalidate then
7061       InvalidateRect(Handle, @R, false);
7062   end;
7063 end;
7064 
7065 procedure TATSynEdit.DoPaintMarkerOfDragDrop(C: TCanvas);
7066 var
7067   Details: TATEditorPosDetails;
7068   NMarkWidth: integer;
7069   PntText, PntCoord: TPoint;
7070   R: TRect;
7071 begin
7072   if not FOptShowDragDropMarker then exit;
7073   if not FMouseDragDropping then exit;
7074   if not FMouseDragDroppingReal then exit;
7075 
7076   PntText:= ClientPosToCaretPos(ScreenToClient(Mouse.CursorPos), Details);
7077   if PntText.Y<0 then exit;
7078   PntCoord:= CaretPosToClientPos(PntText);
7079   if PntCoord.Y<0 then exit;
7080   if not PtInRect(FRectMain, PntCoord) then exit;
7081 
7082   NMarkWidth:= EditorScale(FOptShowDragDropMarkerWidth);
7083   R.Left:= PntCoord.X - NMarkWidth div 2;
7084   R.Right:= R.Left + NMarkWidth;
7085   R.Top:= PntCoord.Y;
7086   R.Bottom:= R.Top + FCharSize.Y; //100% height
7087 
7088   C.Brush.Color:= Colors.Markers;
7089   C.FillRect(R);
7090 
7091   //InvalidateRect(Handle, @R, false); //doens't work for CudaText issue #3784
7092   Invalidate; //fix CudaText issue #3784
7093 end;
7094 
7095 procedure TATSynEdit.TimerBlinkDisable;
7096 begin
7097   if cUsePaintStatic then
7098     FTimerBlink.Enabled:= false;
7099 end;
7100 
7101 procedure TATSynEdit.TimerBlinkEnable;
7102 begin
7103   if cUsePaintStatic then
7104   begin
7105     FTimerBlink.Enabled:= false;
7106     FTimerBlink.Enabled:= FTimersEnabled and FCaretBlinkEnabled;
7107   end;
7108 end;
7109 
7110 
7111 procedure TATSynEdit.DoPaintLineIndent(C: TCanvas;
7112   const ARect: TRect;
7113   ACharSize: TATEditorCharSize;
7114   ACoordY: integer;
7115   AIndentSize: integer;
7116   AColorBG: TColor;
7117   AScrollPos: integer;
7118   AIndentLines: boolean);
7119 var
7120   i: integer;
7121   RBack: TRect;
7122 begin
7123   if AIndentSize=0 then Exit;
7124 
7125   RBack:= Rect(0, 0, AIndentSize*ACharSize.XScaled div ATEditorCharXScale, ACharSize.Y);
7126   OffsetRect(RBack, ARect.Left-AScrollPos*ACharSize.XScaled div ATEditorCharXScale, ACoordY);
7127 
7128   C.Brush.Color:= AColorBG;
7129   C.FillRect(RBack);
7130 
7131   if AIndentLines then
7132     for i:= 0 to AIndentSize-1 do
7133       if i mod FTabSize = 0 then
7134         CanvasLine_DottedVertAlt(C,
7135           Colors.IndentVertLines,
7136           ARect.Left + (i-AScrollPos)*ACharSize.XScaled div ATEditorCharXScale,
7137           ACoordY,
7138           ACoordY+ACharSize.Y);
7139 end;
7140 
7141 procedure TATSynEdit.DoPaintSelectedLineBG(C: TCanvas;
7142   ACharSize: TATEditorCharSize;
7143   const AVisRect: TRect;
7144   APointLeft, APointText: TPoint;
7145   const AWrapItem: TATWrapItem;
7146   ALineWidth: integer;
7147   const AScrollHorz: TATEditorScrollInfo);
7148 var
7149   NLineIndex, NPartXAfter: integer;
7150   NLeft, NRight, i: integer;
7151   Ranges: TATSimpleRangeArray;
7152   RangeFrom, RangeTo: integer;
7153 begin
7154   NLineIndex:= AWrapItem.NLineIndex;
7155 
7156   if not IsSelRectEmpty then
7157   begin
7158    //avoid weird look when empty area is filled in word-wrap mode
7159    if FWrapMode=cWrapOff then
7160     if (NLineIndex>=FSelRect.Top) and (NLineIndex<=FSelRect.Bottom) then
7161     begin
7162       NLeft:= APointLeft.X+ACharSize.XScaled*(FSelRect.Left-AScrollHorz.NPos) div ATEditorCharXScale;
7163       NRight:= NLeft+ACharSize.XScaled*FSelRect.Width div ATEditorCharXScale;
7164       NLeft:= Max(NLeft, APointText.X+ALineWidth);
7165       if (NLeft<NRight) then
7166       begin
7167         C.Brush.Color:= Colors.TextSelBG;
7168         C.FillRect(
7169           NLeft,
7170           APointLeft.Y,
7171           NRight,
7172           APointLeft.Y+ACharSize.Y);
7173       end;
7174     end;
7175   end
7176   else
7177   begin
7178     if not FOptShowFullSel then exit;
7179     NPartXAfter:= AWrapItem.NCharIndex-1+AWrapItem.NLength;
7180 
7181     //here we calculate ranges (XFrom, XTo) where selection(s) overlap current line,
7182     //and then paint fillrect for them
7183     TempSel_GetRangesInLineAfterPoint(NPartXAfter, NLineIndex, Ranges);
7184 
7185     for i:= 0 to Length(Ranges)-1 do
7186     begin
7187       RangeFrom:= Ranges[i].NFrom;
7188       RangeTo:= Ranges[i].NTo;
7189 
7190       //don't paint tail for cases
7191       //1) OptShowFullSel=false
7192       //2) middle WrapItem
7193       if RangeFrom>NPartXAfter then
7194         if (AWrapItem.NFinal=cWrapItemMiddle) then
7195           Continue;
7196 
7197       NLeft:= APointText.X + ALineWidth + (RangeFrom-NPartXAfter)*ACharSize.XScaled div ATEditorCharXScale;
7198       if RangeTo=MaxInt then
7199         NRight:= AVisRect.Right
7200       else
7201         NRight:= NLeft+(RangeTo-RangeFrom)*ACharSize.XScaled div ATEditorCharXScale;
7202 
7203       C.Brush.Color:= Colors.TextSelBG;
7204       C.FillRect(
7205         Max(AVisRect.Left, NLeft),
7206         APointText.Y,
7207         Min(AVisRect.Right, NRight),
7208         APointText.Y+ACharSize.Y
7209         );
7210     end;
7211   {
7212   if FOptShowFullSel then
7213     if AEolSelected then
7214     begin
7215       C.Brush.Color:= Colors.TextSelBG;
7216       C.FillRect(
7217         APointText.X,
7218         APointText.Y,
7219         AVisRect.Right,
7220         APointText.Y+ACharSize.Y);
7221     end;
7222     }
7223   end;
7224 end;
7225 
7226 procedure TATSynEdit.DoPaintNiceScroll(C: TCanvas);
7227 begin
7228   if MouseNiceScroll then
7229     C.Draw(
7230       FMouseNiceScrollPos.X - cBitmapNiceScroll.Height div 2,
7231       FMouseNiceScrollPos.Y - cBitmapNiceScroll.Height div 2,
7232       cBitmapNiceScroll);
7233 end;
7234 
7235 procedure TATSynEdit.DoPaintGutterNumber(C: TCanvas; ALineIndex, ACoordTop: integer; ABand: TATGutterItem);
7236 //painting of text is slower, paint a special mark if possible
7237   //
7238   procedure PaintDash(W, H: integer);
7239   var
7240     P: TPoint;
7241   begin
7242     P.Y:= ACoordTop + FCharSize.Y div 2 - EditorScale(1);
7243 
7244     case FOptNumbersAlignment of
7245       taLeftJustify:
7246         P.X:= ABand.Left + FNumbersIndent;
7247       taRightJustify:
7248         P.X:= ABand.Right - FNumbersIndent - FCharSize.XScaled div ATEditorCharXScale div 2;
7249       taCenter:
7250         P.X:= (ABand.Left+ABand.Right) div 2;
7251     end;
7252 
7253     C.Brush.Color:= C.Font.Color;
7254     C.Brush.Style:= bsSolid;
7255     C.FillRect(
7256       P.X - W div 2,
7257       P.Y,
7258       P.X - W div 2 + W,
7259       P.Y + H
7260       );
7261   end;
7262   //
7263 var
7264   SText: string;
7265   P: TPoint;
7266   NW: integer;
7267 begin
7268   SText:= DoFormatLineNumber(ALineIndex+1);
7269 
7270   case SText of
7271     '':
7272       exit;
7273 
7274     '.':
7275       begin
7276         PaintDash(EditorScale(2), EditorScale(2));
7277       end;
7278 
7279     '-':
7280       begin
7281         PaintDash(FCharSize.XScaled div ATEditorCharXScale, EditorScale(2));
7282       end;
7283 
7284     else
7285       begin
7286         NW:= FCharSize.XScaled * Length(SText) div ATEditorCharXScale;
7287 
7288         P.Y:= ACoordTop;
7289 
7290         case FOptNumbersAlignment of
7291           taLeftJustify:
7292             P.X:= ABand.Left + FNumbersIndent;
7293           taRightJustify:
7294             P.X:= ABand.Right - NW - FNumbersIndent;
7295           taCenter:
7296             P.X:= (ABand.Left + ABand.Right - NW) div 2;
7297         end;
7298 
7299         Inc(P.Y, FTextOffsetFromTop);
7300 
7301         C.Brush.Style:= bsClear;
7302         CanvasTextOutSimplest(C, P.X, P.Y, SText);
7303       end;
7304   end;
7305 end;
7306 
7307 
DoEventCommandnull7308 function TATSynEdit.DoEventCommand(ACommand: integer;
7309   AInvoke: TATEditorCommandInvoke; const AText: string): boolean;
7310 begin
7311   Result:= false;
7312   if Assigned(FOnCommand) then
7313     FOnCommand(Self, ACommand, AInvoke, AText, Result);
7314 end;
7315 
7316 procedure TATSynEdit.DoEventCommandAfter(ACommand: integer; const AText: string);
7317 begin
7318   if Assigned(FOnCommandAfter) then
7319     FOnCommandAfter(Self, ACommand, AText);
7320 end;
7321 
7322 
7323 procedure TATSynEdit.DoEventCarets;
7324 begin
7325   if Assigned(FAdapterHilite) then
7326     FAdapterHilite.OnEditorCaretMove(Self);
7327 
7328   if Assigned(FOnChangeCaretPos) then
7329     FOnChangeCaretPos(Self);
7330 end;
7331 
7332 procedure TATSynEdit.DoEventScroll;
7333 begin
7334   //horizontal scroll must clear CaretItem.SavedX values
7335   Carets.UpdateMemory(cCaretMem_ClearX, false);
7336 
7337   if Assigned(FAdapterHilite) then
7338     FAdapterHilite.OnEditorScroll(Self);
7339 
7340   if Assigned(FOnScroll) then
7341     FOnScroll(Self);
7342 end;
7343 
7344 procedure TATSynEdit.DoEventChange(ALineIndex: integer; AllowOnChange: boolean);
7345 var
7346   HandlerChangeLog: TATStringsChangeLogEvent;
7347 begin
7348   FLinkCache.Clear;
7349 
7350   if Assigned(FAdapterHilite) then
7351   begin
7352     FAdapterHilite.OnEditorChange(Self);
7353 
7354     if ALineIndex>=0 then
7355     begin
7356       HandlerChangeLog:= Strings.OnChangeLog;
7357       if Assigned(HandlerChangeLog) then
7358         HandlerChangeLog(nil, ALineIndex);
7359     end;
7360   end;
7361 
7362   if AllowOnChange then
7363   begin
7364     if Assigned(FOnChange) then
7365       FOnChange(Self);
7366 
7367     if FPrevModified<>Modified then
7368     begin
7369       FPrevModified:= Modified;
7370       if Assigned(FOnChangeModified) then
7371         FOnChangeModified(Self);
7372     end;
7373   end;
7374 
7375   //fire OnIdle after pause after change
7376   if FOptIdleInterval>0 then
7377   begin
7378     FTimerIdle.Enabled:= false;
7379     FTimerIdle.Interval:= FOptIdleInterval;
7380     FTimerIdle.Enabled:= true;
7381   end;
7382 end;
7383 
7384 procedure TATSynEdit.DoEventState;
7385 begin
7386   if Assigned(FOnChangeState) then
7387     FOnChangeState(Self);
7388 end;
7389 
7390 procedure TATSynEdit.DoEventZoom;
7391 begin
7392   if Assigned(FOnChangeZoom) then
7393     FOnChangeZoom(Self);
7394 end;
7395 
7396 procedure TATSynEdit.DoEventClickGutter(ABandIndex, ALineNumber: integer); inline;
7397 begin
7398   if Assigned(FOnClickGutter) then
7399     FOnClickGutter(Self, ABandIndex, ALineNumber);
7400 end;
7401 
7402 procedure TATSynEdit.DoEventClickMicromap(AX, AY: integer); inline;
7403 begin
7404   if Assigned(FOnClickMicromap) then
7405     FOnClickMicromap(Self, AX, AY);
7406 end;
7407 
7408 procedure TATSynEdit.DoEventDrawBookmarkIcon(C: TCanvas; ALineNumber: integer; const ARect: TRect); inline;
7409 begin
7410   if Assigned(FOnDrawBookmarkIcon) then
7411     FOnDrawBookmarkIcon(Self, C, ALineNumber, ARect);
7412 end;
7413 
7414 procedure TATSynEdit.DoEventBeforeCalcHilite; inline;
7415 begin
7416   if Assigned(FAdapterHilite) then
7417     FAdapterHilite.OnEditorBeforeCalcHilite(Self);
7418 
7419   if Assigned(FOnBeforeCalcHilite) then
7420     FOnBeforeCalcHilite(Self);
7421 end;
7422 
7423 
7424 procedure TATSynEdit.DoScrollToBeginOrEnd(AToBegin: boolean);
7425 begin
7426   FScrollHorz.SetZero;
7427   if AToBegin then
7428     FScrollVert.SetZero
7429   else
7430     FScrollVert.SetLast;
7431 
7432   FScrollHorz.NPixelOffset:= 0;
7433   FScrollVert.NPixelOffset:= 0;
7434 
7435   UpdateScrollbars(true);
7436 end;
7437 
7438 procedure TATSynEdit.DoScrollByDelta(ADeltaX, ADeltaY: integer);
7439 //
7440   procedure _Delta(var AInfo: TATEditorScrollInfo; ADelta: integer);
7441   begin
7442     if ADelta=0 then exit;
7443     with AInfo do
7444     begin
7445       NPos:= Max(0, Min(NPosLast, NPos+ADelta));
7446       if (NPos=0) or (NPos>=NPosLast) then
7447         NPixelOffset:= 0;
7448     end;
7449   end;
7450 //
7451 begin
7452   _Delta(FScrollHorz, ADeltaX);
7453   _Delta(FScrollVert, ADeltaY);
7454   UpdateScrollbars(true);
7455 end;
7456 
7457 procedure TATSynEdit.DoScrollByDeltaInPixels(ADeltaX, ADeltaY: integer);
7458 //
7459   procedure _Delta(var AInfo: TATEditorScrollInfo; ADelta: integer);
7460   begin
7461     if ADelta=0 then exit;
7462     UpdateScrollInfoFromSmoothPos(AInfo,
7463       Min(AInfo.SmoothPosLast, AInfo.SmoothPos+ADelta));
7464   end;
7465 //
7466 begin
7467   _Delta(FScrollHorz, ADeltaX);
7468   _Delta(FScrollVert, ADeltaY);
7469 end;
7470 
7471 procedure TATSynEdit.MenuClick(Sender: TObject);
7472 var
7473   Cmd: integer;
7474 begin
7475   Cmd:= (Sender as TMenuItem).Tag;
7476   if Cmd>0 then
7477   begin
7478     DoCommand(Cmd, cInvokeMenuContext);
7479     Invalidate;
7480   end;
7481 end;
7482 
7483 procedure TATSynEdit.MenuStdPopup(Sender: TObject);
7484 var
7485   i: integer;
7486 begin
7487   MenuitemTextCut.Caption:= cStrMenuitemCut;
7488   MenuitemTextCopy.Caption:= cStrMenuitemCopy;
7489   MenuitemTextPaste.Caption:= cStrMenuitemPaste;
7490   MenuitemTextDelete.Caption:= cStrMenuitemDelete;
7491   MenuitemTextSelAll.Caption:= cStrMenuitemSelectAll;
7492   MenuitemTextUndo.Caption:= cStrMenuitemUndo;
7493   MenuitemTextRedo.Caption:= cStrMenuitemRedo;
7494 
7495   for i:= 0 to FMenuStd.Items.Count-1 do
7496     with FMenuStd.Items[i] do
7497     begin
7498       if Assigned(FKeymap) then
7499         ShortCut:= FKeymap.GetShortcutFromCommand(Tag);
7500 
7501       //separator items: hide if read-only, nicer menu
7502       if Caption='-' then
7503         Visible:= not ModeReadOnly;
7504 
7505       case Tag of
7506         cCommand_ClipboardCut:
7507           begin
7508             Enabled:= not ModeReadOnly;
7509             Visible:= not ModeReadOnly;
7510           end;
7511         cCommand_ClipboardPaste:
7512           begin
7513             Enabled:= not ModeReadOnly and Clipboard.HasFormat(CF_Text);
7514             Visible:= not ModeReadOnly;
7515           end;
7516         cCommand_TextDeleteSelection:
7517           begin
7518             Enabled:= not ModeReadOnly and Carets.IsSelection;
7519             Visible:= not ModeReadOnly;
7520           end;
7521         cCommand_Undo:
7522           begin
7523             Enabled:= not ModeReadOnly and (UndoCount>0);
7524             Visible:= not ModeReadOnly;
7525           end;
7526         cCommand_Redo:
7527           begin
7528             Enabled:= not ModeReadOnly and (RedoCount>0);
7529             Visible:= not ModeReadOnly;
7530           end;
7531       end;
7532     end;
7533 end;
7534 
7535 procedure TATSynEdit.InitMenuStd;
7536   //
Addnull7537   function Add(const SName: string; Cmd: integer): TMenuItem; inline;
7538   var
7539     MI: TMenuItem;
7540   begin
7541     MI:= TMenuItem.Create(FMenuStd);
7542     MI.Caption:= SName;
7543     MI.Tag:= Cmd;
7544     MI.OnClick:= @MenuClick;
7545     Result:= MI;
7546     FMenuStd.Items.Add(MI);
7547   end;
7548   //
7549 begin
7550   if FMenuStd=nil then
7551   begin
7552     FMenuStd:= TPopupMenu.Create(Self);
7553     FMenuStd.OnPopup:= @MenuStdPopup;
7554 
7555     MenuitemTextUndo:= Add('Undo', cCommand_Undo);
7556     MenuitemTextRedo:= Add('Redo', cCommand_Redo);
7557     Add('-', 0);
7558     MenuitemTextCut:= Add('Cut', cCommand_ClipboardCut);
7559     MenuitemTextCopy:= Add('Copy', cCommand_ClipboardCopy);
7560     MenuitemTextPaste:= Add('Paste', cCommand_ClipboardPaste);
7561     MenuitemTextDelete:= Add('Delete', cCommand_TextDeleteSelection);
7562     Add('-', 0);
7563     MenuitemTextSelAll:= Add('Select all', cCommand_SelectAll);
7564   end;
7565 end;
7566 
7567 //drop selection of 1st caret into mouse-pos
7568 procedure TATSynEdit.DoDropText(AndDeleteSelection: boolean);
7569 var
7570   St: TATStrings;
7571   Str: atString;
7572   P, PosAfter, Shift: TPoint;
7573   X1, Y1, X2, Y2: integer;
7574   bSel: boolean;
7575   Relation: TATPosRelation;
7576   Details: TATEditorPosDetails;
7577 begin
7578   St:= Strings;
7579   if Carets.Count<>1 then Exit; //allow only 1 caret
7580   Carets[0].GetRange(X1, Y1, X2, Y2, bSel);
7581   if not bSel then Exit;
7582 
7583   DoSelect_None;
7584 
7585   //calc insert-pos
7586   P:= ScreenToClient(Mouse.CursorPos);
7587   P:= ClientPosToCaretPos(P, Details);
7588   if P.Y<0 then exit;
7589 
7590   //can't drop into selection
7591   Relation:= IsPosInRange(P.X, P.Y, X1, Y1, X2, Y2);
7592   if Relation=cRelateInside then exit;
7593 
7594   Str:= St.TextSubstring(X1, Y1, X2, Y2);
7595   if Str='' then exit;
7596 
7597   //insert before selection?
7598   if Relation=cRelateBefore then
7599   begin
7600     if AndDeleteSelection then
7601       St.TextDeleteRange(X1, Y1, X2, Y2, Shift, PosAfter);
7602     St.TextInsert(P.X, P.Y, Str, false, Shift, PosAfter);
7603 
7604     //select moved text
7605     DoCaretSingle(PosAfter.X, PosAfter.Y, P.X, P.Y);
7606   end
7607   else
7608   begin
7609     St.TextInsert(P.X, P.Y, Str, false, Shift, PosAfter);
7610 
7611     //select moved text
7612     DoCaretSingle(PosAfter.X, PosAfter.Y, P.X, P.Y);
7613 
7614     if AndDeleteSelection then
7615     begin
7616       St.TextDeleteRange(X1, Y1, X2, Y2, Shift, PosAfter);
7617       DoCaretsShift(0, X1, Y1, Shift.X, Shift.Y, PosAfter);
7618     end;
7619   end;
7620 
7621   DoEventCarets;
7622   DoEventChange;
7623   Update(true);
7624 end;
7625 
GetIndentStringnull7626 function TATSynEdit.GetIndentString: UnicodeString;
7627 begin
7628   if FOptTabSpaces then
7629     Result:= StringOfCharW(' ', FTabSize)
7630   else
7631     Result:= #9;
7632 end;
7633 
GetAutoIndentStringnull7634 function TATSynEdit.GetAutoIndentString(APosX, APosY: integer; AUseIndentRegexRule: boolean): atString;
7635 var
7636   StrPrev, StrIndent: atString;
7637   NChars, NSpaces: integer;
7638   MatchPos, MatchLen: integer;
7639   bAddIndent: boolean;
7640 begin
7641   Result:= '';
7642   if not FOptAutoIndent then Exit;
7643   if not Strings.IsIndexValid(APosY) then Exit;
7644 
7645   StrPrev:= Strings.LineSub(APosY, 1, APosX);
7646   if StrPrev='' then exit;
7647   NChars:= SGetIndentChars(StrPrev); //count of chars in indent
7648 
7649   bAddIndent:=
7650     AUseIndentRegexRule and
7651     (FOptAutoIndentRegexRule<>'') and
7652     SFindRegexMatch(StrPrev, FOptAutoIndentRegexRule{%H-}, MatchPos, MatchLen);
7653 
7654   StrIndent:= Copy(StrPrev, 1, NChars);
7655   NSpaces:= Length(FTabHelper.TabsToSpaces(APosY, StrIndent));
7656 
7657   case FOptAutoIndentKind of
7658     cIndentAsPrevLine:
7659       Result:= StrIndent;
7660     cIndentSpacesOnly:
7661       Result:= StringOfCharW(' ', NSpaces);
7662     cIndentTabsOnly:
7663       Result:= StringOfCharW(#9, NSpaces div FTabSize);
7664     cIndentTabsAndSpaces:
7665       Result:= StringOfCharW(#9, NSpaces div FTabSize) + StringOfCharW(' ', NSpaces mod FTabSize);
7666     cIndentToOpeningBracket:
7667       begin
7668         //indent like in prev line + spaces up to opening bracket
7669         NSpaces:= SGetIndentCharsToOpeningBracket(StrPrev);
7670         Result:= StrIndent + StringOfCharW(' ', NSpaces-Length(StrIndent));
7671       end;
7672   end;
7673 
7674   if bAddIndent then
7675     Result:= Result+GetIndentString;
7676 end;
7677 
GetModifiednull7678 function TATSynEdit.GetModified: boolean;
7679 begin
7680   Result:= Strings.Modified;
7681 end;
7682 
7683 procedure TATSynEdit.SetModified(AValue: boolean);
7684 begin
7685   Strings.Modified:= AValue;
7686   if AValue then
7687     DoEventChange
7688   else
7689     FPrevModified:= false;
7690 end;
7691 
GetOneLinenull7692 function TATSynEdit.GetOneLine: boolean;
7693 begin
7694   Result:= Strings.OneLine;
7695 end;
7696 
GetRedoCountnull7697 function TATSynEdit.GetRedoCount: integer;
7698 begin
7699   Result:= Strings.RedoCount;
7700 end;
7701 
GetLinesFromTopnull7702 function TATSynEdit.GetLinesFromTop: integer;
7703 var
7704   P: TPoint;
7705 begin
7706   if Carets.Count=0 then
7707     begin Result:= 0; Exit end;
7708   with Carets[0] do
7709     P:= Point(PosX, PosY);
7710   P:= CaretPosToClientPos(P);
7711   Result:= (P.Y-FRectMain.Top) div FCharSize.Y;
7712 end;
7713 
GetTextnull7714 function TATSynEdit.GetText: UnicodeString;
7715 begin
7716   Result:= DoGetTextString;
7717 end;
7718 
DoGetTextStringnull7719 function TATSynEdit.DoGetTextString: atString;
7720 begin
7721   //TATEdit overrides it
7722   Result:= Strings.TextString_Unicode;
7723 end;
7724 
IsRepaintNeededOnEnterOrExitnull7725 function TATSynEdit.IsRepaintNeededOnEnterOrExit: boolean; inline;
7726 begin
7727   Result:=
7728     FOptShowCurLineOnlyFocused or
7729     FOptBorderFocusedActive or
7730     FCaretStopUnfocused;
7731 end;
7732 
7733 procedure TATSynEdit.DoEnter;
7734 begin
7735   inherited;
7736   FIsEntered:= true;
7737   if FCaretHideUnfocused then
7738     FCaretShowEnabled:= true;
7739   if IsRepaintNeededOnEnterOrExit then
7740     Invalidate;
7741   TimersStart;
7742 end;
7743 
7744 procedure TATSynEdit.DoExit;
7745 begin
7746   inherited;
7747   FIsEntered:= false;
7748   if FCaretHideUnfocused then
7749     FCaretShowEnabled:= false;
7750   if IsRepaintNeededOnEnterOrExit then
7751     Invalidate;
7752   TimersStop;
7753 end;
7754 
7755 procedure TATSynEdit.TimersStart;
7756 //TimersStart/Stop are added to minimize count of running timers
7757 begin
7758   FTimersEnabled:= true;
7759   if Assigned(FTimerBlink) then
7760     FTimerBlink.Enabled:= FTimersEnabled and FCaretBlinkEnabled;
7761 end;
7762 
7763 procedure TATSynEdit.TimersStop;
7764 begin
7765   FTimersEnabled:= false;
7766   if Assigned(FTimerBlink) then FTimerBlink.Enabled:= false;
7767   if Assigned(FTimerIdle) then FTimerIdle.Enabled:= false;
7768   if Assigned(FTimerScroll) then FTimerScroll.Enabled:= false;
7769   if Assigned(FTimerNiceScroll) then FTimerNiceScroll.Enabled:= false;
7770 end;
7771 
7772 procedure TATSynEdit.DoMinimapClick(APosY: integer);
7773 var
7774   NItem: integer;
7775 begin
7776   NItem:= GetMinimap_ClickedPosToWrapIndex(APosY);
7777   if NItem>=0 then
7778   begin
7779     NItem:= Max(0, NItem - GetVisibleLines div 2);
7780     DoScroll_SetPos(FScrollVert, Min(NItem, FScrollVert.NMax));
7781     Update;
7782   end;
7783 end;
7784 
7785 procedure TATSynEdit.DoMinimapDrag(APosY: integer);
7786 begin
7787   DoScroll_SetPos(FScrollVert, GetMinimap_DraggedPosToWrapIndex(APosY));
7788   Update;
7789 end;
7790 
GetUndoAsStringnull7791 function TATSynEdit.GetUndoAsString: string;
7792 begin
7793   Result:= Strings.UndoAsString;
7794 end;
7795 
GetRedoAsStringnull7796 function TATSynEdit.GetRedoAsString: string;
7797 begin
7798   Result:= Strings.RedoAsString;
7799 end;
7800 
7801 procedure TATSynEdit.SetUndoLimit(AValue: integer);
7802 begin
7803   FOptUndoLimit:= Max(0, AValue);
7804   Strings.UndoLimit:= FOptUndoLimit;
7805 end;
7806 
GetUndoAfterSavenull7807 function TATSynEdit.GetUndoAfterSave: boolean;
7808 begin
7809   Result:= Strings.UndoAfterSave;
7810 end;
7811 
GetUndoCountnull7812 function TATSynEdit.GetUndoCount: integer;
7813 begin
7814   Result:= Strings.UndoCount;
7815 end;
7816 
7817 procedure TATSynEdit.SetUndoAfterSave(AValue: boolean);
7818 begin
7819   Strings.UndoAfterSave:= AValue;
7820 end;
7821 
7822 procedure TATSynEdit.SetUndoAsString(const AValue: string);
7823 begin
7824   Strings.UndoAsString:= AValue;
7825 end;
7826 
7827 procedure TATSynEdit.DoScaleFontDelta(AInc: boolean; AllowUpdate: boolean);
7828 const
7829   cMinScale = 60;
7830   cStep = 10;
7831 //var
7832 //  NTop: integer;
7833 begin
7834   if FOptScaleFont=0 then
7835   begin
7836     FOptScaleFont:= EditorScaleFontPercents;
7837     if FOptScaleFont=0 then
7838       FOptScaleFont:= EditorScalePercents;
7839   end;
7840 
7841   if not AInc then
7842     if FOptScaleFont<=cMinScale then Exit;
7843 
7844   //NTop:= LineTop;
7845   FOptScaleFont:= FOptScaleFont+cStep*BoolToPlusMinusOne[AInc];
7846   //LineTop:= NTop;
7847 
7848   if AllowUpdate then
7849     Update;
7850 end;
7851 
7852 procedure TATSynEdit.BeginUpdate; inline;
7853 begin
7854   Inc(FPaintLocked);
7855   Invalidate;
7856 end;
7857 
7858 procedure TATSynEdit.EndUpdate; inline;
7859 begin
7860   Dec(FPaintLocked);
7861   if FPaintLocked<0 then
7862     FPaintLocked:= 0;
7863   if FPaintLocked=0 then
7864     Invalidate;
7865 end;
7866 
IsLockednull7867 function TATSynEdit.IsLocked: boolean; inline;
7868 begin
7869   Result:= FPaintLocked>0;
7870 end;
7871 
TextSelectedExnull7872 function TATSynEdit.TextSelectedEx(ACaret: TATCaretItem): atString;
7873 var
7874   X1, Y1, X2, Y2: integer;
7875   bSel: boolean;
7876 begin
7877   Result:= '';
7878   ACaret.GetRange(X1, Y1, X2, Y2, bSel);
7879   if bSel then
7880     Result:= Strings.TextSubstring(X1, Y1, X2, Y2);
7881 end;
7882 
TextSelectednull7883 function TATSynEdit.TextSelected: atString;
7884 begin
7885   if Carets.Count>0 then
7886     Result:= TextSelectedEx(Carets[0])
7887   else
7888     Result:= '';
7889 end;
7890 
TextCurrentWordnull7891 function TATSynEdit.TextCurrentWord: atString;
7892 var
7893   Str: atString;
7894   Caret: TATCaretItem;
7895   N1, N2: integer;
7896 begin
7897   Result:= '';
7898   if Carets.Count=0 then Exit;
7899   Caret:= Carets[0];
7900   Str:= Strings.Lines[Caret.PosY];
7901   SFindWordBounds(Str, Caret.PosX, N1, N2, OptNonWordChars);
7902   if N2>N1 then
7903     Result:= Copy(Str, N1+1, N2-N1);
7904 end;
7905 
GetMouseNiceScrollnull7906 function TATSynEdit.GetMouseNiceScroll: boolean;
7907 begin
7908   Result:= FTimerNiceScroll.Enabled;
7909 end;
7910 
7911 procedure TATSynEdit.SetEnabledSlowEvents(AValue: boolean);
7912 var
7913   St: TATStrings;
7914 begin
7915   St:= Strings;
7916   if not AValue then
7917   begin
7918     St.ClearUndo(true);
7919     St.EnabledChangeEvents:= false;
7920     if Carets.Count>0 then
7921     begin
7922       FLastLineOfSlowEvents:= Carets[0].FirstTouchedLine;
7923       if not St.IsIndexValid(FLastLineOfSlowEvents) then
7924         FLastLineOfSlowEvents:= -1;
7925     end;
7926   end
7927   else
7928   begin
7929     St.ClearUndo(false);
7930     St.EnabledChangeEvents:= true;
7931     if St.IsIndexValid(FLastLineOfSlowEvents) then
7932     begin
7933       St.DoEventLog(FLastLineOfSlowEvents);
7934       St.DoEventChange(cLineChangeEdited, FLastLineOfSlowEvents, 1);
7935       FLastLineOfSlowEvents:= -1;
7936     end;
7937   end;
7938 end;
7939 
7940 procedure TATSynEdit.SetMouseNiceScroll(AValue: boolean);
7941 begin
7942   FTimerNiceScroll.Enabled:= AValue;
7943   if not AValue then
7944     UpdateCursor;
7945   Invalidate;
7946 end;
7947 
GetEndOfFilePosnull7948 function TATSynEdit.GetEndOfFilePos: TPoint;
7949 var
7950   St: TATStrings;
7951 begin
7952   St:= Strings;
7953   if St.Count>0 then
7954   begin
7955     Result.Y:= St.Count-1;
7956     Result.X:= St.LinesLen[Result.Y];
7957     if St.LinesEnds[Result.Y]<>cEndNone then
7958       Inc(Result.X);
7959   end
7960   else
7961   begin
7962     Result.X:= 0;
7963     Result.Y:= 0;
7964   end;
7965 end;
7966 
7967 
DoCalcFoldPropsnull7968 function TATSynEdit.DoCalcFoldProps(AWrapItemIndex: integer; out AProps: TATFoldBarProps): boolean;
7969 var
7970   WrapItem: TATWrapItem;
7971   Rng: PATSynRange;
7972   Caret: TATCaretItem;
7973   NLineIndex: integer;
7974   NIndexOfCurrentRng, NIndexOfCaretRng: integer;
7975 begin
7976   Result:= false;
7977   FillChar(AProps, SizeOf(AProps), 0);
7978 
7979   WrapItem:= FWrapInfo[AWrapItemIndex];
7980   NLineIndex:= WrapItem.NLineIndex;
7981 
7982   //find deepest range which includes caret pos
7983   NIndexOfCaretRng:= -1;
7984   if FOptGutterShowFoldLinesForCaret then
7985     if Carets.Count>0 then
7986     begin
7987       Caret:= Carets[0];
7988       if Strings.IsIndexValid(Caret.PosY) then
7989         NIndexOfCaretRng:= FFold.FindDeepestRangeContainingLine(Caret.PosY, false);
7990     end;
7991 
7992   NIndexOfCurrentRng:= FFold.FindDeepestRangeContainingLine(NLineIndex, false);
7993   if NIndexOfCurrentRng<0 then exit;
7994   AProps.HiliteLines:= NIndexOfCurrentRng=NIndexOfCaretRng;
7995 
7996   Rng:= Fold.ItemPtr(NIndexOfCurrentRng);
7997 
7998   if Rng^.Y<NLineIndex then
7999     AProps.IsLineUp:= true;
8000 
8001   if Rng^.Y2>NLineIndex then
8002     AProps.IsLineDown:= true;
8003 
8004   if Rng^.Y=NLineIndex then
8005   begin
8006     AProps.State:= cFoldbarBegin;
8007     //don't override found [+], 2 blocks can start at same pos
8008     if not AProps.IsPlus then
8009       AProps.IsPlus:= Rng^.Folded;
8010   end;
8011 
8012   if Rng^.Y2=NLineIndex then
8013     if AProps.State<>cFoldbarBegin then
8014       AProps.State:= cFoldbarEnd;
8015 
8016   //correct state for wrapped line
8017   if AProps.State=cFoldbarBegin then
8018     if not WrapItem.bInitial then
8019       AProps.State:= cFoldbarMiddle;
8020 
8021   //correct state for wrapped line
8022   if AProps.State=cFoldbarEnd then
8023     if WrapItem.NFinal=cWrapItemMiddle then
8024       AProps.State:= cFoldbarMiddle;
8025 
8026   Result:= true;
8027 end;
8028 
8029 procedure TATSynEdit.DoPaintGutterFolding(C: TCanvas;
8030   AWrapItemIndex: integer;
8031   ACoordX1, ACoordX2, ACoordY1, ACoordY2: integer);
8032 var
8033   CoordXCenter, CoordYCenter: integer;
8034   Props: TATFoldBarProps;
8035   //
8036   procedure DrawUp; inline;
8037   begin
8038     if Props.IsLineUp then
8039       CanvasLineVert(C,
8040         CoordXCenter,
8041         ACoordY1,
8042         CoordYCenter
8043         );
8044   end;
8045   procedure DrawDown; inline;
8046   begin
8047     if Props.IsLineDown then
8048       CanvasLineVert(C,
8049         CoordXCenter,
8050         CoordYCenter,
8051         ACoordY2+1
8052         );
8053   end;
8054   //
8055 var
8056   NColorLine, NColorPlus: TColor;
8057   NCacheIndex: integer;
8058   bOk: boolean;
8059 begin
8060   if not FOptGutterShowFoldAlways then
8061     if not FCursorOnGutter then exit;
8062 
8063   //FFoldbarCache removes flickering of the folding-bar on fast editing
8064   if FFoldCacheEnabled then
8065   begin
8066     NCacheIndex:= AWrapItemIndex-FFoldbarCacheStart;
8067     if not ((NCacheIndex>=0) and (NCacheIndex<=High(FFoldbarCache))) then exit;
8068 
8069     if not FAdapterIsDataReady then
8070       Props:= FFoldbarCache[NCacheIndex]
8071     else
8072     begin
8073       bOk:= DoCalcFoldProps(AWrapItemIndex, Props);
8074       FFoldbarCache[NCacheIndex]:= Props;
8075       if not bOk then exit;
8076     end;
8077   end
8078   else
8079   begin
8080     bOk:= DoCalcFoldProps(AWrapItemIndex, Props);
8081     if not bOk then exit;
8082   end;
8083 
8084   if Props.HiliteLines then
8085     NColorPlus:= Colors.GutterFoldLine2
8086   else
8087     NColorPlus:= Colors.GutterFoldLine;
8088 
8089   if FOptGutterShowFoldLines then
8090     NColorLine:= NColorPlus
8091   else
8092     NColorLine:= Colors.GutterFoldBG;
8093   C.Pen.Color:= NColorLine;
8094 
8095   CoordXCenter:= (ACoordX1+ACoordX2) div 2;
8096   CoordYCenter:= (ACoordY1+ACoordY2) div 2;
8097 
8098   case Props.State of
8099     cFoldbarBegin:
8100       begin
8101         if FOptGutterShowFoldLinesAll then
8102         begin
8103           DrawUp;
8104           DrawDown;
8105         end;
8106 
8107         if not Props.IsPlus then
8108           DrawDown;
8109 
8110         DoPaintGutterPlusMinus(C,
8111           CoordXCenter, CoordYCenter, Props.IsPlus, NColorPlus);
8112       end;
8113     cFoldbarEnd:
8114       begin
8115         if FOptGutterShowFoldLinesAll then
8116         begin
8117           DrawUp;
8118           DrawDown;
8119         end;
8120 
8121         Dec(ACoordY2, cSizeGutterFoldLineDx);
8122         CanvasLineVert(C,
8123           CoordXCenter,
8124           ACoordY1,
8125           ACoordY2
8126           );
8127         CanvasLineHorz(C,
8128           CoordXCenter,
8129           ACoordY2,
8130           CoordXCenter + EditorScale(FOptGutterPlusSize)
8131           );
8132       end;
8133     cFoldbarMiddle:
8134       begin
8135         CanvasLineVert(C,
8136           CoordXCenter,
8137           ACoordY1,
8138           ACoordY2
8139           );
8140       end;
8141     else
8142       begin
8143         DrawUp;
8144         DrawDown;
8145       end;
8146   end;
8147 end;
8148 
8149 procedure TATSynEdit.DoPaintGutterDecor(C: TCanvas; ALine: integer; const ARect: TRect);
8150 var
8151   Decor: TATGutterDecorItem;
8152   Style, StylePrev: TFontStyles;
8153   Ext: TSize;
8154   N, NText: integer;
8155 begin
8156   if FGutterDecor=nil then exit;
8157   N:= FGutterDecor.Find(ALine);
8158   if N<0 then exit;
8159   Decor:= FGutterDecor[N];
8160 
8161   //paint decor text
8162   if Decor.Data.Text<>'' then
8163   begin
8164     C.Font.Color:= Decor.Data.TextColor;
8165     Style:= [];
8166     if Decor.Data.TextBold then
8167       Include(Style, fsBold);
8168     if Decor.Data.TextItalic then
8169       Include(Style, fsItalic);
8170     StylePrev:= C.Font.Style;
8171     C.Font.Style:= Style;
8172 
8173     Ext:= C.TextExtent(Decor.Data.Text);
8174     C.Brush.Color:= Colors.GutterBG;
8175 
8176     case FGutterDecorAlignment of
8177       taCenter:
8178         NText:= (ARect.Left+ARect.Right-Ext.cx) div 2;
8179       taLeftJustify:
8180         NText:= ARect.Left;
8181       taRightJustify:
8182         NText:= ARect.Right-Ext.cx;
8183     end;
8184 
8185     C.Brush.Style:= bsClear;
8186     C.TextOut(
8187       NText,
8188       (ARect.Top+ARect.Bottom-Ext.cy) div 2,
8189       Decor.Data.Text
8190       );
8191     C.Font.Style:= StylePrev;
8192   end
8193   else
8194   //paint decor icon
8195   if Assigned(FGutterDecorImages) then
8196   begin
8197     N:= Decor.Data.ImageIndex;
8198     if (N>=0) and (N<FGutterDecorImages.Count) then
8199       FGutterDecorImages.Draw(C,
8200         (ARect.Left+ARect.Right-FGutterDecorImages.Width) div 2,
8201         (ARect.Top+ARect.Bottom-FGutterDecorImages.Height) div 2,
8202         N
8203         );
8204   end;
8205 end;
8206 
8207 procedure TATSynEdit.DoPaintTextHintTo(C: TCanvas);
8208 var
8209   Size: TSize;
8210   Pos: TPoint;
8211 begin
8212   C.Brush.Color:= FColorBG;
8213   C.Font.Color:= Colors.TextHintFont;
8214   C.Font.Style:= FTextHintFontStyle;
8215 
8216   Size:= C.TextExtent(FTextHint);
8217   if FTextHintCenter then
8218   begin
8219     Pos:= CenterPoint(FRectMain);
8220     Dec(Pos.X, Size.cx div 2);
8221     Dec(Pos.Y, Size.cy div 2);
8222   end
8223   else
8224   begin
8225     Pos:= FTextOffset;
8226   end;
8227 
8228   C.Brush.Style:= bsClear;
8229   C.TextOut(Pos.X, Pos.Y, FTextHint);
8230 end;
8231 
8232 
8233 procedure TATSynEdit.CMWantSpecialKey(var Message: TCMWantSpecialKey);
8234 begin
8235   case Message.CharCode of
8236     VK_RETURN: Message.Result:= Ord(WantReturns);
8237     VK_TAB: Message.Result:= Ord(WantTabs);
8238     VK_LEFT,
8239     VK_RIGHT,
8240     VK_UP,
8241     VK_DOWN: Message.Result:= 1;
8242     else inherited;
8243   end;
8244 end;
8245 
8246 {$ifdef GTK2_IME_CODE}
8247 // fcitx IM
8248 procedure TATSynEdit.WM_GTK_IM_COMPOSITION(var Message: TLMessage);
8249 var
8250   buffer: atString;
8251   len: Integer;
8252   bOverwrite, bSelect: Boolean;
8253   Caret: TATCaretItem;
8254 begin
8255   //exit;-
8256   //exiting, currently it breaks CudaText issue #3442
8257 
8258   if (not ModeReadOnly) then
8259   begin
8260     // set candidate position
8261     if (Message.WParam and (GTK_IM_FLAG_START or GTK_IM_FLAG_PREEDIT))<>0 then
8262     begin
8263       if Carets.Count>0 then
8264       begin
8265         Caret:= Carets[0];
8266         IM_Context_Set_Cursor_Pos(Caret.CoordX,Caret.CoordY+TextCharSize.Y);
8267       end;
8268     end;
8269     // valid string at composition & commit
8270     if Message.WParam and (GTK_IM_FLAG_COMMIT or GTK_IM_FLAG_PREEDIT)<>0 then
8271     begin
8272 	  if Message.WParam and GTK_IM_FLAG_REPLACE=0 then
8273         FIMSelText:=TextSelected;
8274       // insert preedit or commit string
8275       buffer:=UTF8Decode(pchar(Message.LParam));
8276       len:=Length(buffer);
8277       bOverwrite:=ModeOverwrite and (Length(FIMSelText)=0);
8278       bSelect:=len>0;
8279       // commit
8280       if len>0 then
8281       begin
8282         if Message.WParam and GTK_IM_FLAG_COMMIT<>0 then
8283         begin
8284           TextInsertAtCarets(buffer, False, bOverwrite, False);
8285           FIMSelText:='';
8286         end else
8287           TextInsertAtCarets(buffer, False, False, bSelect);
8288       end else
8289         // fix for IBUS IM.
8290         if Message.WParam and GTK_IM_FLAG_REPLACE<>0 then
8291           TextInsertAtCarets('',False, bOverwrite, False);
8292     end;
8293     // end composition
8294     // To Do : skip insert saved selection after commit with ibus.
8295     if (Message.WParam and GTK_IM_FLAG_END<>0) and (FIMSelText<>'') then
8296       TextInsertAtCarets(FIMSelText, False, False, False);
8297   end;
8298 end;
8299 {$endif}
8300 
8301 procedure TATSynEdit.DoPaintStaple(C: TCanvas; const R: TRect; AColor: TColor);
8302 var
8303   X1, Y1, X2, Y2: integer;
8304 begin
8305   if FOptStapleStyle=cLineStyleNone then Exit;
8306 
8307   if FOptStapleEdge1=cStapleEdgeAngle then
8308     CanvasLineEx(C, AColor, FOptStapleStyle, R.Left, R.Top, R.Right, R.Top, false);
8309 
8310   X1:= R.Left;
8311   Y1:= R.Top;
8312   X2:= R.Left;
8313   Y2:= R.Bottom;
8314   if FOptStapleEdge1=cStapleEdgeNone then
8315     Inc(Y1, FCharSize.Y);
8316   if FOptStapleEdge2=cStapleEdgeNone then
8317     Dec(Y2, FCharSize.Y);
8318 
8319   CanvasLineEx(C, AColor, FOptStapleStyle, X1, Y1, X2, Y2, false);
8320 
8321   if FOptStapleEdge2=cStapleEdgeAngle then
8322     CanvasLineEx(C, AColor, FOptStapleStyle, R.Left, R.Bottom, R.Right, R.Bottom, true);
8323 end;
8324 
8325 procedure TATSynEdit.DoPaintStaples(C: TCanvas; const ARect: TRect;
8326   ACharSize: TATEditorCharSize; const AScrollHorz: TATEditorScrollInfo);
8327 var
8328   St: TATStrings;
8329   nLineFrom, nLineTo, nRangeDeepest, nMaxHeight: integer;
8330   nIndent, nIndentBegin, nIndentEnd: integer;
8331   Indexes: TATIntArray;
8332   Range: PATSynRange;
8333   P1, P2: TPoint;
8334   RSt: TRect;
8335   NColor, NColorNormal, NColorActive: TColor;
8336   i: integer;
8337 begin
8338   if FOptStapleStyle=cLineStyleNone then Exit;
8339   if not FFold.HasStaples then Exit;
8340 
8341   St:= Strings;
8342   nLineFrom:= LineTop;
8343   nLineTo:= LineBottom;
8344   nMaxHeight:= FRectMain.Height+2;
8345   nRangeDeepest:= -1;
8346 
8347   Indexes:= FFold.FindRangesWithStaples(nLineFrom, nLineTo);
8348 
8349   //currently find active range for first caret only
8350   if FOptStapleHiliteActive then
8351     if Carets.Count>0 then
8352       nRangeDeepest:= FFold.FindDeepestRangeContainingLine(Carets[0].PosY, true);
8353 
8354   NColorNormal:= Colors.BlockStaple;
8355   NColorActive:= Colors.BlockStapleForCaret;
8356   if NColorActive=clNone then
8357     NColorActive:= ColorBlend(NColorNormal, FColorFont, FOptStapleHiliteActiveAlpha);
8358 
8359   for i:= 0 to High(Indexes) do
8360   begin
8361     Range:= Fold.ItemPtr(Indexes[i]);
8362     {
8363     //FindRangesWithStaples does it:
8364     if not Range^.Staple then Continue;
8365     if Range^.Folded then Continue;
8366     }
8367 
8368     if not St.IsIndexValid(Range^.Y) then Continue;
8369     if not St.IsIndexValid(Range^.Y2) then Continue;
8370 
8371     if IsLineFolded(Range^.Y, true) then Continue;
8372     if IsLineFolded(Range^.Y2, true) then Continue;
8373 
8374     P1:= CaretPosToClientPos(Point(0, Range^.Y));
8375     P2:= CaretPosToClientPos(Point(0, Range^.Y2));
8376     if (P1.Y<FRectMain.Top) and (Range^.Y>=nLineFrom) then Continue;
8377     if (P2.Y<FRectMain.Top) and (Range^.Y2>=nLineFrom) then Continue;
8378 
8379     nIndentBegin:= FTabHelper.GetIndentExpanded(Range^.Y, St.Lines[Range^.Y]);
8380 
8381     if FOptStapleIndentConsidersEnd then
8382     begin
8383       nIndentEnd:= FTabHelper.GetIndentExpanded(Range^.Y2, St.Lines[Range^.Y2]);
8384       nIndent:= Min(nIndentBegin, nIndentEnd);
8385     end
8386     else
8387       nIndent:= nIndentBegin;
8388 
8389     Inc(P1.X, nIndent*ACharSize.XScaled div ATEditorCharXScale);
8390     Inc(P2.X, nIndent*ACharSize.XScaled div ATEditorCharXScale);
8391 
8392     RSt.Left:= P1.X + FOptStapleIndent;
8393     RSt.Top:= P1.Y;
8394     RSt.Right:= RSt.Left+ (ACharSize.XScaled * FOptStapleWidthPercent div ATEditorCharXScale div 100);
8395     RSt.Bottom:= P2.Y + ACharSize.Y-1;
8396 
8397     if (RSt.Left>=ARect.Left) and
8398       (RSt.Left<ARect.Right) then
8399     begin
8400       //don't use too big coords, some OS'es truncate lines painted with big coords
8401       RSt.Top:= Max(RSt.Top, -2);
8402       RSt.Bottom:= Min(RSt.Bottom, nMaxHeight);
8403 
8404       if Indexes[i]=nRangeDeepest then
8405         NColor:= NColorActive
8406       else
8407         NColor:= NColorNormal;
8408 
8409       if Assigned(FOnCalcStaple) then
8410         FOnCalcStaple(Self, Range^.Y, NIndent, NColor);
8411 
8412       DoPaintStaple(C, RSt, NColor);
8413     end;
8414   end;
8415 end;
8416 
8417 
IsCharWordnull8418 function TATSynEdit.IsCharWord(ch: Widechar): boolean;
8419 begin
8420   Result:= ATStringProc.IsCharWord(ch, OptNonWordChars);
8421 end;
8422 
TATSynEdit.GetGapsnull8423 function TATSynEdit.GetGaps: TATGaps;
8424 begin
8425   Result:= Strings.Gaps;
8426 end;
8427 
TATSynEdit.GetLastCommandChangedLinesnull8428 function TATSynEdit.GetLastCommandChangedLines: integer;
8429 begin
8430   Result:= Strings.LastCommandChangedLines;
8431 end;
8432 
8433 procedure TATSynEdit.SetLastCommandChangedLines(AValue: integer);
8434 begin
8435   Strings.LastCommandChangedLines:= AValue;
8436 end;
8437 
8438 procedure TATSynEdit.DoPaintMarkersTo(C: TCanvas);
8439 var
8440   Mark: TATMarkerItem;
8441   Pnt: TPoint;
8442   NMarkSize, NLineW: integer;
8443   iMark: integer;
8444   R: TRect;
8445 begin
8446   if FMarkers=nil then exit;
8447 
8448   NMarkSize:= Max(1, FCharSize.Y * FOptMarkersSize div (100*2));
8449   NLineW:= NMarkSize;
8450 
8451   for iMark:= 0 to FMarkers.Count-1 do
8452   begin
8453     Mark:= FMarkers[iMark];
8454     if Mark.CoordX<0 then Continue;
8455     if Mark.CoordY<0 then Continue;
8456 
8457     Pnt.X:= Mark.CoordX;
8458     Pnt.Y:= Mark.CoordY+FCharSize.Y;
8459 
8460     if PtInRect(FRectMain, Pnt) then
8461       CanvasPaintTriangleUp(C, Colors.Markers, Pnt, NMarkSize);
8462 
8463     if (Mark.LineLen<>0) and (Mark.CoordY=Mark.CoordY2) then
8464     begin
8465       R.Left:= Min(Pnt.X, Mark.CoordX2);
8466       R.Right:= Max(Pnt.X, Mark.CoordX2)+1;
8467       R.Bottom:= Pnt.Y+NMarkSize+1;
8468       R.Top:= R.Bottom-NLineW;
8469 
8470       //avoid painting part of the line over minimap/gutter
8471       R.Left:= Max(R.Left, FRectMain.Left);
8472       R.Right:= Min(R.Right, FRectMain.Right);
8473 
8474       C.Brush.Color:= Colors.Markers;
8475       C.FillRect(R);
8476     end;
8477   end;
8478 end;
8479 
8480 procedure TATSynEdit.DoPaintGutterPlusMinus(C: TCanvas; AX, AY: integer;
8481   APlus: boolean; ALineColor: TColor);
8482 begin
8483   Inc(AY, FTextOffsetFromTop);
8484 
8485   case OptGutterIcons of
8486     cGutterIconsPlusMinus:
8487       begin
8488         CanvasPaintPlusMinus(C,
8489           ALineColor,
8490           Colors.GutterFoldBG,
8491           Point(AX, AY),
8492           EditorScale(FOptGutterPlusSize),
8493           APlus);
8494       end;
8495     cGutterIconsTriangles:
8496       begin
8497         if APlus then
8498           CanvasPaintTriangleRight(C,
8499             ALineColor,
8500             Point(AX, AY),
8501             EditorScale(FOptGutterPlusSize div 2))
8502         else
8503           CanvasPaintTriangleDown(C,
8504             ALineColor,
8505             Point(AX, AY),
8506             EditorScale(FOptGutterPlusSize div 2))
8507       end;
8508   end;
8509 end;
8510 
8511 
8512 procedure TATSynEdit.DoSetMarkedLines(ALine1, ALine2: integer);
8513 begin
8514   InitMarkedRange;
8515   FMarkedRange.Clear;
8516   if (ALine1>=0) and (ALine2>=ALine1) then
8517   begin
8518     FMarkedRange.Add(0, ALine1);
8519     FMarkedRange.Add(0, ALine2);
8520   end;
8521 end;
8522 
8523 procedure TATSynEdit.DoGetMarkedLines(out ALine1, ALine2: integer);
8524 begin
8525   ALine1:= -1;
8526   ALine2:= -1;
8527   if Assigned(FMarkedRange) then
8528     if FMarkedRange.Count=2 then
8529     begin
8530       ALine1:= FMarkedRange.Items[0].PosY;
8531       ALine2:= FMarkedRange.Items[1].PosY;
8532     end;
8533 end;
8534 
8535 
8536 procedure TATSynEdit.UpdateLinksAttribs;
8537 var
8538   St: TATStrings;
8539   AtrObj: TATLinePartClass;
8540   NLineStart, NLineEnd, NLineLen: integer;
8541   MatchPos, MatchLen, iLine: integer;
8542   LinkArrayPtr: PATLinkArray;
8543   LinkArray: TATLinkArray;
8544   LinkIndex: integer;
8545   NRegexRuns: integer;
8546 begin
8547   if ModeOneLine then
8548     exit;
8549 
8550   if not OptShowURLs then
8551   begin
8552     if Assigned(FAttribs) then
8553       FAttribs.DeleteWithTag(cUrlMarkerTag);
8554     exit;
8555   end;
8556 
8557   St:= Strings;
8558   NLineStart:= LineTop;
8559   NLineEnd:= NLineStart+GetVisibleLines;
8560 
8561   InitAttribs;
8562   FAttribs.DeleteWithTag(cUrlMarkerTag);
8563 
8564   FLinkCache.DeleteDataOutOfRange(NLineStart, NLineEnd);
8565   NRegexRuns:= 0;
8566 
8567   for iLine:= NLineStart to NLineEnd do
8568   begin
8569     if not St.IsIndexValid(iLine) then Break;
8570     NLineLen:= St.LinesLen[iLine];
8571 
8572     if NLineLen<FOptMinLineLenToCalcURL then Continue;
8573     if NLineLen>FOptMaxLineLenToCalcURL then Continue;
8574 
8575     LinkArrayPtr:= FLinkCache.FindData(iLine);
8576     if LinkArrayPtr=nil then
8577     begin
8578       Assert(Assigned(FRegexLinks), 'FRegexLinks not inited');
8579       FRegexLinks.InputString:= St.Lines[iLine];
8580 
8581       LinkIndex:= 0;
8582       FillChar(LinkArray, SizeOf(LinkArray), 0);
8583       MatchPos:= 0;
8584       MatchLen:= 0;
8585       Inc(NRegexRuns);
8586 
8587       while FRegexLinks.ExecPos(MatchPos+MatchLen+1) do
8588       begin
8589         MatchPos:= FRegexLinks.MatchPos[0];
8590         MatchLen:= FRegexLinks.MatchLen[0];
8591         LinkArray[LinkIndex].NFrom:= MatchPos;
8592         LinkArray[LinkIndex].NLen:= MatchLen;
8593         Inc(LinkIndex);
8594         if LinkIndex>High(LinkArray) then Break;
8595         Inc(NRegexRuns);
8596       end;
8597 
8598       FLinkCache.AddData(iLine, LinkArray);
8599       LinkArrayPtr:= @LinkArray;
8600     end;
8601 
8602     for LinkIndex:= 0 to High(LinkArray) do
8603     begin
8604       MatchLen:= LinkArrayPtr^[LinkIndex].NLen;
8605       if MatchLen=0 then Break;
8606       MatchPos:= LinkArrayPtr^[LinkIndex].NFrom;
8607 
8608       AtrObj:= TATLinePartClass.Create;
8609       AtrObj.Data.ColorFont:= Colors.Links;
8610       AtrObj.Data.ColorBG:= clNone;
8611       AtrObj.Data.ColorBorder:= Colors.Links;
8612       AtrObj.Data.BorderDown:= cLineStyleSolid;
8613 
8614       FAttribs.Add(
8615         MatchPos-1,
8616         iLine,
8617         cUrlMarkerTag,
8618         MatchLen,
8619         0,
8620         AtrObj
8621         );
8622     end;
8623   end;
8624 
8625   ////debug
8626   //Application.MainForm.Caption:= 'runs:'+IntToStr(NRegexRuns)+' '+FLinkCache.DebugText;
8627 end;
8628 
8629 
TATSynEdit.DoGetLinkAtPosnull8630 function TATSynEdit.DoGetLinkAtPos(AX, AY: integer): atString;
8631 var
8632   MatchPos, MatchLen: integer;
8633 begin
8634   Result:= '';
8635   if not Strings.IsIndexValid(AY) then exit;
8636 
8637   Assert(Assigned(FRegexLinks), 'FRegexLinks not inited');
8638   FRegexLinks.InputString:= Strings.Lines[AY];
8639   MatchPos:= 0;
8640   MatchLen:= 0;
8641 
8642   while FRegexLinks.ExecPos(MatchPos+MatchLen+1) do
8643   begin
8644     MatchPos:= FRegexLinks.MatchPos[0]-1;
8645     MatchLen:= FRegexLinks.MatchLen[0];
8646     if MatchPos>AX then
8647       Break;
8648     if (MatchPos<=AX) and (MatchPos+MatchLen>AX) then
8649       exit(FRegexLinks.Match[0]);
8650   end;
8651 end;
8652 
8653 
8654 procedure TATSynEdit.DragOver(Source: TObject; X, Y: Integer;
8655   State: TDragState; var Accept: Boolean);
8656 begin
8657   Accept:=
8658     FOptMouseDragDrop and
8659     (not ModeReadOnly) and
8660     (not ModeOneLine) and
8661     (Source is TATSynEdit) and
8662     ((Source as TATSynEdit).TextSelected<>'');
8663 end;
8664 
8665 procedure TATSynEdit.DragDrop(Source: TObject; X, Y: Integer);
8666 var
8667   SText: atString;
8668   Pnt: TPoint;
8669   Details: TATEditorPosDetails;
8670 begin
8671   if not (Source is TATSynEdit) then exit;
8672   if (Source=Self) then exit;
8673   SText:= (Source as TATSynedit).TextSelected;
8674   if SText='' then exit;
8675 
8676   Pnt:= ClientPosToCaretPos(Point(X, Y), Details);
8677   if Strings.IsIndexValid(Pnt.Y) then
8678   begin
8679     DoCaretSingle(Pnt.X, Pnt.Y);
8680     DoCommand(cCommand_TextInsert, cInvokeInternal, SText);
8681     if ATEditorOptions.MouseDragDropFocusesTargetEditor then
8682       SetFocus;
8683 
8684     //Ctrl not pressed: delete block from src
8685     if FOptMouseDragDropCopyingWithState in GetKeyShiftState then
8686       (Source as TATSynedit).DoCommand(cCommand_TextDeleteSelection, cInvokeInternal);
8687   end;
8688 end;
8689 
8690 procedure TATSynEdit.OnNewScrollbarVertChanged(Sender: TObject);
8691 var
8692   Msg: TLMVScroll;
8693   NPos: Int64;
8694 begin
8695   if FScrollbarLock then exit;
8696 
8697   if FMicromapOnScrollbar then
8698   begin
8699     NPos:= FScrollbarVert.Position
8700            div FScrollbarVert.SmallChange; //this supports OptScrollSmooth
8701     DoUnfoldLine(NPos);
8702     LineTop:= NPos;
8703   end
8704   else
8705   begin
8706     FillChar(Msg{%H-}, SizeOf(Msg), 0);
8707     Msg.ScrollCode:= SB_THUMBPOSITION;
8708     Msg.Pos:= FScrollbarVert.Position;
8709     WMVScroll(Msg);
8710   end;
8711 
8712   //show scroll hint
8713   DoHintShow;
8714 end;
8715 
8716 procedure TATSynEdit.OnNewScrollbarHorzChanged(Sender: TObject);
8717 var
8718   Msg: TLMHScroll;
8719 begin
8720   if FScrollbarLock then exit;
8721   FillChar({%H-}Msg, SizeOf(Msg), 0);
8722   Msg.ScrollCode:= SB_THUMBPOSITION;
8723   Msg.Pos:= FScrollbarHorz.Position;
8724   WMHScroll(Msg);
8725 end;
8726 
8727 procedure TATSynEdit.TimerIdleTick(Sender: TObject);
8728 begin
8729   FTimerIdle.Enabled:= false;
8730   if Assigned(FOnIdle) then
8731     FOnIdle(Self);
8732   if Assigned(FAdapterHilite) then
8733     FAdapterHilite.OnEditorIdle(Self);
8734 end;
8735 
8736 procedure TATSynEdit.DoStringsOnChangeEx(Sender: TObject; AChange: TATLineChangeKind; ALine, AItemCount: integer);
8737 //we are called inside BeginEditing/EndEditing - just remember top edited line
8738 var
8739   St: TATStrings;
8740 begin
8741   St:= Strings;
8742   if St.EditingActive then
8743   begin
8744   end
8745   else
8746     FlushEditingChangeEx(AChange, ALine, AItemCount);
8747 end;
8748 
8749 procedure TATSynEdit.DoStringsOnChangeLog(Sender: TObject; ALine: integer);
8750 var
8751   St: TATStrings;
8752 begin
8753   St:= Strings;
8754   if St.EditingActive then
8755   begin
8756   end
8757   else
8758     FlushEditingChangeLog(ALine);
8759 end;
8760 
8761 procedure TATSynEdit.FlushEditingChangeEx(AChange: TATLineChangeKind; ALine, AItemCount: integer);
8762 begin
8763   Fold.Update(AChange, ALine, AItemCount);
8764 
8765   if Assigned(FAdapterHilite) then
8766     FAdapterHilite.OnEditorChangeEx(Self, AChange, ALine, AItemCount);
8767 end;
8768 
8769 procedure TATSynEdit.FlushEditingChangeLog(ALine: integer);
8770 begin
8771   if Assigned(FOnChangeLog) then
8772     FOnChangeLog(Self, ALine);
8773 end;
8774 
8775 procedure TATSynEdit.StartTimerDelayedParsing;
8776 begin
8777   FTimerDelayedParsing.Enabled:= false;
8778   FTimerDelayedParsing.Enabled:= true;
8779   if Carets.Count>0 then
8780     FLastCommandDelayedParsingOnLine:= Min(
8781       FLastCommandDelayedParsingOnLine,
8782       Max(0, Carets[0].FirstTouchedLine-1)
8783       );
8784 end;
8785 
8786 procedure TATSynEdit.TimerDelayedParsingTick(Sender: TObject);
8787 //to solve CudaText issue #3403
8788 //const
8789 //  c: integer=0;
8790 begin
8791   FTimerDelayedParsing.Enabled:= false;
8792   if Assigned(FOnChangeLog) then
8793     FOnChangeLog(Self, FLastCommandDelayedParsingOnLine);
8794   {
8795   //debug
8796   inc(c);
8797   Application.MainForm.Caption:= 'delayed parse: '+inttostr(c)+': '+inttostr(FLastCommandDelayedParsingOnLine);
8798   }
8799   FLastCommandDelayedParsingOnLine:= MaxInt;
8800 end;
8801 
8802 procedure TATSynEdit.TimerFlickerTick(Sender: TObject);
8803 begin
8804   FTimerFlicker.Enabled:= false;
8805   Include(FPaintFlags, cIntFlagBitmap);
8806   inherited Invalidate;
8807 end;
8808 
8809 procedure TATSynEdit.DoStringsOnProgress(Sender: TObject);
8810 begin
8811   Invalidate;
8812   Application.ProcessMessages;
8813   //auto paints "wait... N%"
8814 end;
8815 
8816 procedure TATSynEdit.DoHotspotsExit;
8817 begin
8818   if FLastHotspot>=0 then
8819   begin
8820     if Assigned(FOnHotspotExit) then
8821       FOnHotspotExit(Self, FLastHotspot);
8822     FLastHotspot:= -1;
8823   end;
8824 end;
8825 
8826 
8827 procedure TATSynEdit.DoPaintTextFragment(C: TCanvas;
8828   const ARect: TRect;
8829   ALineFrom, ALineTo: integer;
8830   AConsiderWrapInfo: boolean;
8831   AColorBG, AColorBorder: TColor);
8832 var
8833   St: TATStrings;
8834   NOutputStrWidth: Int64;
8835   NLine, NWrapIndex: integer;
8836   NColorAfter: TColor;
8837   WrapItem: TATWrapItem;
8838   TextOutProps: TATCanvasTextOutProps;
8839   SText: UnicodeString;
8840 begin
8841   St:= Strings;
8842   C.Brush.Color:= AColorBG;
8843   C.FillRect(ARect);
8844 
8845   FillChar(TextOutProps{%H-}, SizeOf(TextOutProps), 0);
8846 
8847   TextOutProps.Editor:= Self;
8848   TextOutProps.TabHelper:= FTabHelper;
8849   TextOutProps.CharSize:= FCharSize;
8850   TextOutProps.CharsSkipped:= 0;
8851   TextOutProps.DrawEvent:= nil;
8852   TextOutProps.ControlWidth:= ARect.Width;
8853   TextOutProps.TextOffsetFromLine:= FTextOffsetFromTop;
8854 
8855   TextOutProps.ShowUnprinted:= FUnprintedVisible and FUnprintedSpaces;
8856   TextOutProps.ShowUnprintedSpacesTrailing:= FUnprintedSpacesTrailing;
8857   TextOutProps.ShowUnprintedSpacesBothEnds:= FUnprintedSpacesBothEnds;
8858   TextOutProps.ShowUnprintedSpacesOnlyInSelection:= FUnprintedSpacesOnlyInSelection;
8859   TextOutProps.DetectIsPosSelected:= @IsPosSelected;
8860 
8861   TextOutProps.ShowFontLigatures:= FOptShowFontLigatures;
8862   TextOutProps.ColorNormalFont:= Colors.TextFont;
8863   TextOutProps.ColorUnprintedFont:= Colors.UnprintedFont;
8864   TextOutProps.ColorUnprintedHexFont:= Colors.UnprintedHexFont;
8865 
8866   TextOutProps.FontNormal_Name:= Font.Name;
8867   TextOutProps.FontNormal_Size:= DoScaleFont(Font.Size);
8868 
8869   TextOutProps.FontItalic_Name:= FontItalic.Name;
8870   TextOutProps.FontItalic_Size:= DoScaleFont(FontItalic.Size);
8871 
8872   TextOutProps.FontBold_Name:= FontBold.Name;
8873   TextOutProps.FontBold_Size:= DoScaleFont(FontBold.Size);
8874 
8875   TextOutProps.FontBoldItalic_Name:= FontBoldItalic.Name;
8876   TextOutProps.FontBoldItalic_Size:= DoScaleFont(FontBoldItalic.Size);
8877 
8878   if AConsiderWrapInfo then
8879     NWrapIndex:= WrapInfo.FindIndexOfCaretPos(Point(0, ALineFrom));
8880 
8881   for NLine:= ALineFrom to ALineTo do
8882   begin
8883     NColorAfter:= clNone;
8884     if AConsiderWrapInfo then
8885     begin
8886       if NWrapIndex<0 then Break;
8887       WrapItem:= WrapInfo[NWrapIndex];
8888       Inc(NWrapIndex);
8889     end
8890     else
8891     begin
8892       if not St.IsIndexValid(NLine) then Break;
8893       FillChar(WrapItem, SizeOf(WrapItem), 0);
8894       WrapItem.NLineIndex:= NLine;
8895       WrapItem.NCharIndex:= 1;
8896       WrapItem.NLength:= St.LinesLen[NLine];
8897     end;
8898 
8899     DoCalcLineHilite(
8900       WrapItem,
8901       FParts{%H-},
8902       0, cMaxCharsForOutput,
8903       AColorBG,
8904       false,
8905       NColorAfter,
8906       true);
8907 
8908     SText:= St.LineSub(
8909         WrapItem.NLineIndex,
8910         WrapItem.NCharIndex,
8911         GetVisibleColumns);
8912 
8913     if FOptMaskCharUsed then
8914       SText:= StringOfCharW(FOptMaskChar, Length(SText));
8915 
8916     TextOutProps.HasAsciiNoTabs:= St.LinesHasAsciiNoTabs[WrapItem.NLineIndex];
8917     TextOutProps.SuperFast:= false;
8918     TextOutProps.LineIndex:= WrapItem.NLineIndex;
8919     TextOutProps.CharIndexInLine:= WrapItem.NCharIndex;
8920     CanvasTextOut(C,
8921       cSizeIndentTooltipX + WrapItem.NIndent*FCharSize.XScaled div ATEditorCharXScale,
8922       cSizeIndentTooltipY + FCharSize.Y*(NLine-ALineFrom),
8923       SText,
8924       @FParts,
8925       NOutputStrWidth,
8926       TextOutProps
8927       )
8928    end;
8929 
8930   C.Brush.Color:= AColorBorder;
8931   C.FrameRect(ARect);
8932 end;
8933 
8934 
8935 procedure TATSynEdit.DoPaintMinimapTooltip(C: TCanvas);
8936 var
8937   C_Bmp: TCanvas;
8938   RectAll: TRect;
8939   Pnt: TPoint;
8940   NWrapIndex, NLineCenter, NLineTop, NLineBottom: integer;
8941   NPanelLeft, NPanelTop, NPanelWidth, NPanelHeight: integer;
8942 begin
8943   Pnt:= ScreenToClient(Mouse.CursorPos);
8944 
8945   NPanelWidth:= FRectMain.Width * FMinimapTooltipWidthPercents div 100;
8946   if FMinimapAtLeft then
8947     NPanelLeft:= FRectMinimap.Right + 1
8948   else
8949     NPanelLeft:= FRectMinimap.Left - NPanelWidth - 1;
8950   NPanelHeight:= FMinimapTooltipLinesCount*FCharSize.Y + 2;
8951   NPanelTop:= Max(0, Min(ClientHeight-NPanelHeight,
8952     Pnt.Y - FCharSize.Y*FMinimapTooltipLinesCount div 2 ));
8953 
8954   if FMinimapTooltipBitmap=nil then
8955     FMinimapTooltipBitmap:= TBitmap.Create;
8956   FMinimapTooltipBitmap.SetSize(NPanelWidth, NPanelHeight);
8957 
8958   RectAll:= Rect(0, 0, NPanelWidth, NPanelHeight);
8959   C_Bmp:= FMinimapTooltipBitmap.Canvas;
8960   C_Bmp.Pen.Color:= Colors.MinimapTooltipBorder;
8961   C_Bmp.Brush.Color:= Colors.MinimapTooltipBG;
8962   C_Bmp.Rectangle(RectAll);
8963 
8964   NWrapIndex:= GetMinimap_ClickedPosToWrapIndex(Pnt.Y);
8965   if NWrapIndex<0 then exit;
8966   NLineCenter:= FWrapInfo[NWrapIndex].NLineIndex;
8967   NLineTop:= Max(0, NLineCenter - FMinimapTooltipLinesCount div 2);
8968   NLineBottom:= Min(NLineTop + FMinimapTooltipLinesCount-1, Strings.Count-1);
8969 
8970   DoPaintTextFragment(C_Bmp, RectAll,
8971     NLineTop,
8972     NLineBottom,
8973     true,
8974     Colors.MinimapTooltipBG,
8975     Colors.MinimapTooltipBorder
8976     );
8977 
8978   C.Draw(NPanelLeft, NPanelTop, FMinimapTooltipBitmap);
8979 end;
8980 
8981 
8982 procedure TATSynEdit.UpdateFoldedMarkTooltip;
8983 begin
8984   if (not FFoldTooltipVisible) or not FFoldedMarkCurrent.IsInited then
8985   begin
8986     if Assigned(FFoldedMarkTooltip) then
8987       FFoldedMarkTooltip.Hide;
8988     exit
8989   end;
8990 
8991   InitFoldedMarkTooltip;
8992 
8993   FFoldedMarkTooltip.Width:= FRectMain.Width * FFoldTooltipWidthPercents div 100;
8994   FFoldedMarkTooltip.Height:= (FFoldedMarkCurrent.LineTo-FFoldedMarkCurrent.LineFrom+1) * FCharSize.Y + 2;
8995   FFoldedMarkTooltip.Left:= Min(
8996     FRectMain.Right - FFoldedMarkTooltip.Width - 1,
8997     FFoldedMarkCurrent.Coord.Left);
8998   FFoldedMarkTooltip.Top:=
8999     FFoldedMarkCurrent.Coord.Top + FCharSize.Y;
9000 
9001   //no space for on bottom? show on top
9002   if FFoldedMarkTooltip.Top + FFoldedMarkTooltip.Height > FRectMain.Bottom then
9003     if FFoldedMarkCurrent.Coord.Top - FFoldedMarkTooltip.Height >= FRectMain.Top then
9004       FFoldedMarkTooltip.Top:= FFoldedMarkCurrent.Coord.Top - FFoldedMarkTooltip.Height;
9005 
9006   FFoldedMarkTooltip.Show;
9007   FFoldedMarkTooltip.Invalidate;
9008 end;
9009 
9010 procedure TATSynEdit.FoldedMarkTooltipPaint(Sender: TObject);
9011 begin
9012   if FFoldedMarkCurrent.IsInited then
9013     DoPaintTextFragment(
9014       FFoldedMarkTooltip.Canvas,
9015       Rect(0, 0, FFoldedMarkTooltip.Width, FFoldedMarkTooltip.Height),
9016       FFoldedMarkCurrent.LineFrom,
9017       FFoldedMarkCurrent.LineTo,
9018       false, //to paint fully folded lines, must be False
9019       Colors.MinimapTooltipBG,
9020       Colors.MinimapTooltipBorder
9021       );
9022 end;
9023 
9024 procedure TATSynEdit.FoldedMarkMouseEnter(Sender: TObject);
9025 begin
9026   if Assigned(FFoldedMarkTooltip) then
9027     FFoldedMarkTooltip.Hide;
9028 end;
9029 
TATSynEdit.DoGetFoldedMarkLinesCountnull9030 function TATSynEdit.DoGetFoldedMarkLinesCount(ALine: integer): integer;
9031 var
9032   St: TATStrings;
9033   i: integer;
9034 begin
9035   Result:= 1;
9036   St:= Strings;
9037   for i:= ALine+1 to Min(ALine+FFoldTooltipLineCount-1, St.Count-1) do
9038     if St.LinesHidden[i, FEditorIndex] then
9039       Inc(Result)
9040     else
9041       Break;
9042 end;
9043 
9044 
TATSynEdit.DoGetGapRectnull9045 function TATSynEdit.DoGetGapRect(AIndex: integer; out ARect: TRect): boolean;
9046 var
9047   GapItem: TATGapItem;
9048   Pnt: TPoint;
9049 begin
9050   Result:= false;
9051   ARect:= Rect(0, 0, 0, 0);
9052 
9053   if not Gaps.IsIndexValid(AIndex) then exit;
9054   GapItem:= Gaps.Items[AIndex];
9055   Pnt:= CaretPosToClientPos(Point(0, GapItem.LineIndex+1));
9056 
9057   ARect.Left:= FRectMain.Left;
9058   ARect.Right:= FRectMain.Right;
9059   ARect.Top:= Pnt.Y - GapItem.Size;
9060   ARect.Bottom:= Pnt.Y;
9061 
9062   //gap can be scrolled away: return False
9063   if ARect.Bottom<=FRectMain.Top then exit;
9064   if ARect.Top>=FRectMain.Bottom then exit;
9065 
9066   Result:= true;
9067 end;
9068 
9069 procedure TATSynEdit.SetFontItalic(AValue: TFont);
9070 begin
9071   FFontItalic.Assign(AValue);
9072 end;
9073 
9074 procedure TATSynEdit.SetFontBold(AValue: TFont);
9075 begin
9076   FFontBold.Assign(AValue);
9077 end;
9078 
9079 procedure TATSynEdit.SetFontBoldItalic(AValue: TFont);
9080 begin
9081   FFontBoldItalic.Assign(AValue);
9082 end;
9083 
9084 procedure TATSynEdit.UpdateTabHelper;
9085 begin
9086   FTabHelper.TabSpaces:= OptTabSpaces;
9087   FTabHelper.TabSize:= OptTabSize;
9088   FTabHelper.IndentSize:= OptIndentSize;
9089   FTabHelper.SenderObj:= Self;
9090   FTabHelper.OnCalcTabSize:= FOnCalcTabSize;
9091   FTabHelper.OnCalcLineLen:= @DoCalcLineLen;
9092 end;
9093 
9094 procedure TATSynEdit.DoPaintTiming(C: TCanvas);
9095 var
9096   S: string;
9097 begin
9098   if ModeOneLine then exit;
9099   if GetVisibleLines<10 then exit;
9100 
9101   C.Font.Name:= Font.Name;
9102   C.Font.Color:= clRed;
9103   C.Font.Size:= 8;
9104 
9105   S:= Format('#%03d, %d+%d ms', [FPaintCounter, FTickAll, FTickMinimap]);
9106   CanvasTextOutSimplest(C, 5, 5, S);
9107 end;
9108 
9109 
TATSynEdit.GetEncodingNamenull9110 function TATSynEdit.GetEncodingName: string;
9111 var
9112   St: TATStrings;
9113 begin
9114   St:= Strings;
9115   case St.Encoding of
9116     cEncAnsi:
9117       begin
9118         Result:= cEncConvNames[St.EncodingCodepage];
9119       end;
9120     cEncUTF8:
9121       begin
9122         if St.SaveSignUtf8 then
9123           Result:= cEncNameUtf8_WithBom
9124         else
9125           Result:= cEncNameUtf8_NoBom;
9126       end;
9127     cEncWideLE:
9128       begin
9129         if St.SaveSignWide then
9130           Result:= cEncNameUtf16LE_WithBom
9131         else
9132           Result:= cEncNameUtf16LE_NoBom;
9133       end;
9134     cEncWideBE:
9135       begin
9136         if St.SaveSignWide then
9137           Result:= cEncNameUtf16BE_WithBom
9138         else
9139           Result:= cEncNameUtf16BE_NoBom;
9140       end;
9141     cEnc32LE:
9142       begin
9143         if St.SaveSignWide then
9144           Result:= cEncNameUtf32LE_WithBom
9145         else
9146           Result:= cEncNameUtf32LE_NoBom;
9147       end;
9148     cEnc32BE:
9149       begin
9150         if St.SaveSignWide then
9151           Result:= cEncNameUtf32BE_WithBom
9152         else
9153           Result:= cEncNameUtf32BE_NoBom;
9154       end;
9155   end;
9156 end;
9157 
9158 procedure TATSynEdit.SetEncodingName(const AName: string);
9159 var
9160   St: TATStrings;
9161 begin
9162   if AName='' then exit;
9163   if SameText(AName, GetEncodingName) then exit;
9164   St:= Strings;
9165 
9166   if SameText(AName, cEncNameUtf8_WithBom) then begin St.Encoding:= cEncUTF8; St.SaveSignUtf8:= true; end else
9167   if SameText(AName, cEncNameUtf8_NoBom) then begin St.Encoding:= cEncUTF8; St.SaveSignUtf8:= false; end else
9168   if SameText(AName, cEncNameUtf16LE_WithBom) then begin St.Encoding:= cEncWideLE; St.SaveSignWide:= true; end else
9169   if SameText(AName, cEncNameUtf16LE_NoBom) then begin St.Encoding:= cEncWideLE; St.SaveSignWide:= false; end else
9170   if SameText(AName, cEncNameUtf16BE_WithBom) then begin St.Encoding:= cEncWideBE; St.SaveSignWide:= true; end else
9171   if SameText(AName, cEncNameUtf16BE_NoBom) then begin St.Encoding:= cEncWideBE; St.SaveSignWide:= false; end else
9172   if SameText(AName, cEncNameUtf32LE_WithBom) then begin St.Encoding:= cEnc32LE; St.SaveSignWide:= true; end else
9173   if SameText(AName, cEncNameUtf32LE_NoBom) then begin St.Encoding:= cEnc32LE; St.SaveSignWide:= false; end else
9174   if SameText(AName, cEncNameUtf32BE_WithBom) then begin St.Encoding:= cEnc32BE; St.SaveSignWide:= true; end else
9175   if SameText(AName, cEncNameUtf32BE_NoBom) then begin St.Encoding:= cEnc32BE; St.SaveSignWide:= false; end else
9176   begin
9177     St.Encoding:= cEncAnsi;
9178     St.EncodingCodepage:= EncConvFindEncoding(LowerCase(AName));
9179   end;
9180 end;
9181 
9182 procedure TATSynEdit.TextInsertAtCarets(const AText: atString; AKeepCaret,
9183   AOvrMode, ASelectThen: boolean);
9184 var
9185   Res: TATCommandResults;
9186 begin
9187   Res:= DoCommand_TextInsertAtCarets(AText, AKeepCaret, AOvrMode, ASelectThen, false);
9188   DoCommandResults(0, Res);
9189 end;
9190 
9191 procedure TATSynEdit.DoCaretsFixForSurrogatePairs(AMoveRight: boolean);
9192 //this is used to prevert caret stopping
9193 //a) inside surrogate pair (2 codes which make one glyph)
9194 //b) on accent (combining) char; we skip _all_ chars (Unicode allows several accent chars)
9195 var
9196   St: TATStrings;
9197   Caret: TATCaretItem;
9198   ch: WideChar;
9199   i: integer;
9200 begin
9201   St:= Strings;
9202   for i:= 0 to Carets.Count-1 do
9203   begin
9204     Caret:= Carets[i];
9205     if Caret.PosX<=0 then Continue;
9206     if not St.IsIndexValid(Caret.PosY) then Continue;
9207     ch:= St.LineCharAt(Caret.PosY, Caret.PosX+1);
9208     if ch=#0 then Continue;
9209 
9210     if IsCharSurrogateLow(ch) then
9211     begin
9212       Caret.PosX:= Caret.PosX+BoolToPlusMinusOne[AMoveRight];
9213       Continue;
9214     end;
9215 
9216     while IsCharAccent(ch) do
9217     begin
9218       Caret.PosX:= Caret.PosX+BoolToPlusMinusOne[AMoveRight];
9219       ch:= St.LineCharAt(Caret.PosY, Caret.PosX+1);
9220     end;
9221   end;
9222 end;
9223 
RectMicromapMarknull9224 function TATSynEdit.RectMicromapMark(AColumn, ALineFrom, ALineTo: integer;
9225   AMapHeight, AMinMarkHeight: integer): TRect;
9226 //to make things safe, don't pass the ARect, but only its height
9227 begin
9228   if FMicromap.IsIndexValid(AColumn) then
9229   begin
9230     if ALineFrom>=0 then
9231       Result.Top:= Int64(ALineFrom) * AMapHeight div FMicromapScaleDiv
9232     else
9233       Result.Top:= 0;
9234 
9235     if ALineTo>=0 then
9236       Result.Bottom:= Max(Result.Top + AMinMarkHeight,
9237                           Int64(ALineTo+1) * AMapHeight div FMicromapScaleDiv)
9238     else
9239       Result.Bottom:= AMapHeight;
9240 
9241     with FMicromap.Columns[AColumn] do
9242     begin
9243       Result.Left:= NLeft;
9244       Result.Right:= NRight;
9245     end;
9246   end
9247   else
9248     Result:= cRectEmpty;
9249 end;
9250 
9251 procedure TATSynEdit.SetShowOsBarVert(AValue: boolean);
9252 begin
9253   if FShowOsBarVert=AValue then Exit;
9254   FShowOsBarVert:= AValue;
9255   ShowScrollBar(Handle, SB_Vert, AValue);
9256 end;
9257 
9258 procedure TATSynEdit.SetShowOsBarHorz(AValue: boolean);
9259 begin
9260   if FShowOsBarHorz=AValue then Exit;
9261   FShowOsBarHorz:= AValue;
9262   ShowScrollBar(Handle, SB_Horz, AValue);
9263 end;
9264 
9265 procedure TATSynEdit.InitFoldedMarkList;
9266 begin
9267   if FFoldedMarkList=nil then
9268     FFoldedMarkList:= TATFoldedMarks.Create;
9269 end;
9270 
9271 procedure TATSynEdit.InitFoldedMarkTooltip;
9272 begin
9273   if FFoldedMarkTooltip=nil then
9274   begin
9275     FFoldedMarkTooltip:= TPanel.Create(Self);
9276     FFoldedMarkTooltip.Hide;
9277     FFoldedMarkTooltip.Width:= 15;
9278     FFoldedMarkTooltip.Height:= 15;
9279     FFoldedMarkTooltip.Parent:= Self;
9280     FFoldedMarkTooltip.BorderStyle:= bsNone;
9281     FFoldedMarkTooltip.OnPaint:= @FoldedMarkTooltipPaint;
9282     FFoldedMarkTooltip.OnMouseEnter:=@FoldedMarkMouseEnter;
9283   end;
9284 end;
9285 
9286 procedure TATSynEdit.InitAttribs;
9287 begin
9288   if FAttribs=nil then
9289   begin
9290     FAttribs:= TATMarkers.Create;
9291     FAttribs.Sorted:= true;
9292     FAttribs.Duplicates:= true; //CudaText plugins need it
9293   end;
9294 end;
9295 
9296 procedure TATSynEdit.InitMarkers;
9297 begin
9298   if FMarkers=nil then
9299   begin
9300     FMarkers:= TATMarkers.Create;
9301     FMarkers.Sorted:= false;
9302   end;
9303 end;
9304 
9305 procedure TATSynEdit.InitHotspots;
9306 begin
9307   if FHotspots=nil then
9308     FHotspots:= TATHotspots.Create;
9309 end;
9310 
9311 procedure TATSynEdit.InitDimRanges;
9312 begin
9313   if FDimRanges=nil then
9314     FDimRanges:= TATDimRanges.Create;
9315 end;
9316 
9317 procedure TATSynEdit.InitGutterDecor;
9318 begin
9319   if FGutterDecor=nil then
9320     FGutterDecor:= TATGutterDecor.Create;
9321 end;
9322 
GetAttribsnull9323 function TATSynEdit.GetAttribs: TATMarkers;
9324 begin
9325   InitAttribs;
9326   Result:= FAttribs;
9327 end;
9328 
DoCalcLineLennull9329 function TATSynEdit.DoCalcLineLen(ALineIndex: integer): integer;
9330 begin
9331   Result:= Strings.LinesLen[ALineIndex];
9332 end;
9333 
GetDimRangesnull9334 function TATSynEdit.GetDimRanges: TATDimRanges;
9335 begin
9336   InitDimRanges;
9337   Result:= FDimRanges;
9338 end;
9339 
GetHotspotsnull9340 function TATSynEdit.GetHotspots: TATHotspots;
9341 begin
9342   InitHotspots;
9343   Result:= FHotspots;
9344 end;
9345 
GetMarkersnull9346 function TATSynEdit.GetMarkers: TATMarkers;
9347 begin
9348   InitMarkers;
9349   Result:= FMarkers;
9350 end;
9351 
GetGutterDecornull9352 function TATSynEdit.GetGutterDecor: TATGutterDecor;
9353 begin
9354   InitGutterDecor;
9355   Result:= FGutterDecor;
9356 end;
9357 
9358 procedure TATSynEdit.SetOptShowURLsRegex(const AValue: string);
9359 begin
9360   if FOptShowURLsRegex=AValue then Exit;
9361   FOptShowURLsRegex:= AValue;
9362   UpdateLinksRegexObject;
9363 end;
9364 
9365 procedure TATSynEdit.InitMarkedRange;
9366 begin
9367   if FMarkedRange=nil then
9368   begin
9369     FMarkedRange:= TATMarkers.Create;
9370     FMarkedRange.Sorted:= true;
9371   end;
9372 end;
9373 
DoScaleFontnull9374 function TATSynEdit.DoScaleFont(AValue: integer): integer;
9375 begin
9376   if FOptScaleFont>0 then
9377     Result:= AValue * FOptScaleFont div 100
9378   else
9379     Result:= EditorScaleFont(AValue);
9380 end;
9381 
UpdateLinksRegexObjectnull9382 function TATSynEdit.UpdateLinksRegexObject: boolean;
9383 begin
9384   Result:= false;
9385 
9386   if FRegexLinks=nil then
9387     FRegexLinks:= TRegExpr.Create;
9388 
9389   try
9390     //FRegexLinks.UseUnicodeWordDetection:= false; //faster for links
9391     FRegexLinks.ModifierS:= false;
9392     FRegexLinks.ModifierM:= false; //M not needed
9393     FRegexLinks.ModifierI:= false; //I not needed to find links
9394     FRegexLinks.Expression:= FOptShowURLsRegex{%H-};
9395     FRegexLinks.Compile;
9396 
9397     Result:= true;
9398   except
9399     exit;
9400   end;
9401 end;
9402 
9403 
GetFoldingAsStringnull9404 function TATSynEdit.GetFoldingAsString: string;
9405 var
9406   L: TStringList;
9407   i: integer;
9408   R: PATSynRange;
9409 begin
9410   Result:= '';
9411   L:= TStringList.Create;
9412   try
9413     L.LineBreak:= ',';
9414     for i:= 0 to Fold.Count-1 do
9415     begin
9416       R:= Fold.ItemPtr(i);
9417       if R^.Folded then
9418         L.Add(IntToStr(R^.Y));
9419     end;
9420     Result:= L.Text;
9421   finally
9422     L.Free;
9423   end;
9424 end;
9425 
9426 procedure TATSynEdit.SetFoldingAsString(const AValue: string);
9427 var
9428   St: TATStrings;
9429   Sep: TATStringSeparator;
9430   NLineTop, NLine, NRange: integer;
9431   bChange: boolean;
9432 begin
9433   DoCommand(cCommand_UnfoldAll, cInvokeInternal);
9434   NLineTop:= LineTop;
9435   bChange:= false;
9436 
9437   St:= Strings;
9438   Sep.Init(AValue);
9439   repeat
9440     if not Sep.GetItemInt(NLine, -1) then Break;
9441 
9442     if not St.IsIndexValid(NLine) then Continue;
9443 
9444     NRange:= Fold.FindRangeWithPlusAtLine(NLine);
9445     if NRange<0 then Continue;
9446 
9447     if not Fold.ItemPtr(NRange)^.Folded then
9448     begin
9449       bChange:= true;
9450       DoRangeFold(NRange);
9451     end;
9452   until false;
9453 
9454   if bChange then
9455   begin
9456     if FScrollHorz.NPos>0 then
9457     begin
9458       //fix changed horz scroll, CudaText issue #1439
9459       FScrollHorz.SetZero;
9460 
9461       //SetZero may scroll view out of caret
9462       DoGotoCaret(cEdgeTop);
9463     end;
9464 
9465     //keep LineTop! CudaText issue #3055
9466     LineTop:= NLineTop;
9467 
9468     Update;
9469   end;
9470 end;
9471 
9472 procedure TATSynEdit.UpdateAndWait(AUpdateWrapInfo: boolean; APause: integer);
9473 begin
9474   Update(AUpdateWrapInfo);
9475   Paint;
9476   Application.ProcessMessages;
9477   Sleep(APause);
9478 end;
9479 
IsPosInVisibleAreanull9480 function TATSynEdit.IsPosInVisibleArea(AX, AY: integer): boolean;
9481 var
9482   Pnt: TPoint;
9483   NTop, NCount: integer;
9484 begin
9485   NTop:= LineTop;
9486   if AY<NTop then
9487     exit(false);
9488 
9489   NCount:= Strings.Count;
9490   if NCount<=1 then
9491     exit(true);
9492 
9493   if OptWrapMode=cWrapOff then
9494   begin
9495     Result:= AY<=NTop+GetVisibleLines;
9496   end
9497   else
9498   begin
9499     if AY>LineBottom then
9500       exit(false);
9501 
9502     Pnt:= CaretPosToClientPos(Point(AX, AY));
9503     if Pnt.Y=-1 then
9504       exit(true);
9505 
9506     Result:= PtInRect(FRectMainVisible, Pnt);
9507   end;
9508 end;
9509 
9510 procedure TATSynEdit.DoStringsOnUndoBefore(Sender: TObject; AX, AY: integer);
9511 var
9512   OldOption: boolean;
9513   Tick: QWord;
9514 begin
9515   FLastUndoPaused:= false;
9516 
9517   if ModeOneLine then exit;
9518   if FOptUndoPause<=0 then exit;
9519   if Carets.Count>1 then exit;
9520   if AY<0 then exit;
9521   if AY>=Strings.Count then exit; //must have for the case: big file; Ctrl+A, Del; Undo
9522   if IsPosInVisibleArea(AX, AY) then exit;
9523 
9524   Tick:= GetTickCount64;
9525   if FLastUndoTick>0 then
9526     if Tick-FLastUndoTick<FOptUndoPause2 then
9527       exit;
9528 
9529   FLastUndoPaused:= true;
9530   FLastUndoTick:= Tick;
9531 
9532   if FOptUndoPauseHighlightLine then
9533   begin
9534     OldOption:= OptShowCurLine;
9535     OptShowCurLine:= true;
9536   end;
9537 
9538   DoGotoPos(
9539     Point(AX, AY),
9540     Point(-1, -1),
9541     FOptUndoIndentHorz,
9542     FOptUndoIndentVert,
9543     true,
9544     true,
9545     false,
9546     false);
9547   { //not good
9548   DoShowPos(
9549     Point(0, ALine),
9550     FOptUndoIndentHorz,
9551     FOptUndoIndentVert,
9552     true,
9553     true);
9554     }
9555 
9556   UpdateAndWait(true, FOptUndoPause);
9557 
9558   if FOptUndoPauseHighlightLine then
9559     OptShowCurLine:= OldOption;
9560 end;
9561 
9562 procedure TATSynEdit.DoStringsOnUndoAfter(Sender: TObject; AX, AY: integer);
9563 var
9564   OldOption: boolean;
9565 begin
9566   if not FLastUndoPaused then exit;
9567   {
9568   if ModeOneLine then exit;
9569   if FOptUndoPause<=0 then exit;
9570   if AY<0 then exit;
9571   if AY>=Strings.Count then exit; //must have for the case: big file; Ctrl+A, Del; Undo
9572   if IsPosInVisibleArea(AX, AY) then exit;
9573   }
9574 
9575   if FOptUndoPauseHighlightLine then
9576   begin
9577     OldOption:= OptShowCurLine;
9578     OptShowCurLine:= true;
9579   end;
9580 
9581   UpdateAndWait(true, FOptUndoPause);
9582 
9583   if FOptUndoPauseHighlightLine then
9584     OptShowCurLine:= OldOption;
9585 end;
9586 
9587 procedure TATSynEdit.ActionAddJumpToUndo;
9588 var
9589   St: TATStrings;
9590 begin
9591   St:= Strings;
9592   if FOptUndoForCaretJump then
9593   begin
9594     St.SetGroupMark; //solve CudaText #3269
9595     St.ActionAddJumpToUndo(St.CaretsAfterLastEdition);
9596     //ActionAddJumpToUndo(GetCaretsArray); //bad, parameter is needed only for another array
9597   end;
9598 end;
9599 
9600 
9601 procedure TATSynEdit.BeginEditing;
9602 var
9603   St: TATStrings;
9604 begin
9605   St:= Strings;
9606   St.EditingActive:= true;
9607   St.EditingTopLine:= -1;
9608 end;
9609 
9610 procedure TATSynEdit.EndEditing(ATextChanged: boolean);
9611 var
9612   St: TATStrings;
9613 begin
9614   St:= Strings;
9615   St.EditingActive:= false;
9616   if ATextChanged then
9617     if St.EditingTopLine>=0 then
9618     begin
9619       //FlushEditingChangeEx(cLineChangeEdited, FEditingTopLine, 1); //not needed
9620       FlushEditingChangeLog(St.EditingTopLine);
9621     end;
9622 end;
9623 
9624 procedure TATSynEdit.UpdateGapForms(ABeforePaint: boolean);
9625 var
9626   Gap: TATGapItem;
9627   i: integer;
9628 begin
9629   if ABeforePaint then
9630   begin
9631     for i:= 0 to Gaps.Count-1 do
9632     begin
9633       Gap:= Gaps[i];
9634       if Assigned(Gap.Form) then
9635         Gap.FormVisible:= false;
9636     end;
9637   end
9638   else
9639   begin
9640     for i:= 0 to Gaps.Count-1 do
9641     begin
9642       Gap:= Gaps[i];
9643       if Assigned(Gap.Form) then
9644         Gap.Form.Visible:= Gap.FormVisible;
9645     end;
9646   end;
9647 end;
9648 
9649 procedure TATSynEdit.SetOptScaleFont(AValue: integer);
9650 begin
9651   if FOptScaleFont=AValue then Exit;
9652   FOptScaleFont:=AValue;
9653   UpdateInitialVars(Canvas);
9654 end;
9655 
9656 procedure TATSynEdit.InitFoldbarCache(ACacheStartIndex: integer);
9657 var
9658   NCount: integer;
9659   bLenValid, bClear: boolean;
9660 begin
9661   NCount:= GetVisibleLines+1;
9662 
9663   bClear:= false;
9664   if FFoldbarCacheStart<>ACacheStartIndex then
9665     bClear:= true;
9666   bLenValid:= Length(FFoldbarCache)=NCount;
9667   if not bLenValid then
9668     bClear:= true;
9669 
9670   FFoldbarCacheStart:= ACacheStartIndex;
9671 
9672   if not bLenValid then
9673     SetLength(FFoldbarCache, NCount);
9674 
9675   if bClear then
9676     FillChar(FFoldbarCache[0], SizeOf(TATFoldBarProps)*NCount, 0);
9677 end;
9678 
9679 procedure TATSynEdit.DoHandleWheelRecord(const ARec: TATEditorWheelRecord);
9680 begin
9681   case ARec.Kind of
9682     wqkVert:
9683       begin
9684         //w/o this handler wheel works only with OS scrollbars, need with new scrollbars too
9685         DoScrollByDeltaInPixels(
9686           0,
9687           FCharSize.Y * -FOptMouseWheelScrollVertSpeed * ARec.Delta div 120
9688           );
9689       end;
9690 
9691     wqkHorz:
9692       begin
9693         DoScrollByDelta(
9694           -FOptMouseWheelScrollHorzSpeed * ARec.Delta div 120,
9695           0
9696           );
9697       end;
9698 
9699     wqkZoom:
9700       begin
9701         DoScaleFontDelta(ARec.Delta>0, false);
9702         DoEventZoom;
9703       end;
9704   end;
9705 end;
9706 
9707 {
9708 procedure TATSynEdit.DoHandleWheelQueue;
9709 var
9710   Rec: TATEditorWheelRecord;
9711 begin
9712   while FWheelQueue.Size()>0 do
9713   begin
9714     Rec:= FWheelQueue.Front;
9715     FWheelQueue.Pop();
9716     DoHandleWheelRecord(Rec);
9717   end;
9718 end;
9719 }
9720 
9721 
9722 {$I atsynedit_carets.inc}
9723 {$I atsynedit_hilite.inc}
9724 {$I atsynedit_sel.inc}
9725 {$I atsynedit_fold.inc}
9726 {$I atsynedit_debug.inc}
9727 
9728 {$R res/nicescroll1.res}
9729 {$R res/nicescroll2.res}
9730 {$R res/foldbar.res}
9731 {$R res/editor_hourglass.res}
9732 
9733 {$I atsynedit_cmd_handler.inc}
9734 {$I atsynedit_cmd_keys.inc}
9735 {$I atsynedit_cmd_sel.inc}
9736 {$I atsynedit_cmd_editing.inc}
9737 {$I atsynedit_cmd_clipboard.inc}
9738 {$I atsynedit_cmd_misc.inc}
9739 {$I atsynedit_cmd_bookmark.inc}
9740 {$I atsynedit_cmd_markers.inc}
9741 
9742 
9743 initialization
9744   ATClipboardColumnFormat:= RegisterClipboardFormat('Application/X-ATSynEdit-Block');
9745 
9746   RegExprModifierS:= False;
9747   RegExprModifierM:= True;
9748   {$ifndef USE_FPC_REGEXPR}
9749   RegExprUsePairedBreak:= False;
9750   RegExprReplaceLineBreak:= #10;
9751   {$endif}
9752 
9753 finalization
9754   FreeEditorResources;
9755 
9756 end.
9757 
9758