ScintEdit.pas 103 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065
  1. unit ScintEdit;
  2. {
  3. Inno Setup
  4. Copyright (C) 1997-2024 Jordan Russell
  5. Portions by Martijn Laan
  6. For conditions of distribution and use, see LICENSE.TXT.
  7. TScintEdit component: a VCL wrapper for Scintilla
  8. }
  9. interface
  10. uses
  11. Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Generics.Collections, ScintInt;
  12. const
  13. StyleNumbers = 32; { The syntax highlighting can use up to 32 styles }
  14. StyleNumberBits = 5; { 5 bits are needed to store 32 values }
  15. StyleNumberMask = StyleNumbers-1; { To get the 5 bits from a byte it needs to be AND-ed with $1F = 31 }
  16. StyleNumberUnusedBits = 8-StyleNumberBits; { 3 bits of a byte are unused }
  17. type
  18. TScintChangeHistory = (schDisabled, schMarkers, schIndicators);
  19. TScintCommand = type NativeInt;
  20. TScintEditAutoCompleteSelectionEvent = TNotifyEvent;
  21. TScintEditCallTipArrowClick = procedure(Sender: TObject; const Up: Boolean) of object;
  22. TScintEditChangeInfo = record
  23. Inserting: Boolean;
  24. StartPos, Length, LinesDelta: Integer;
  25. end;
  26. TScintEditChangeEvent = procedure(Sender: TObject;
  27. const Info: TScintEditChangeInfo) of object;
  28. TScintEditCharAddedEvent = procedure(Sender: TObject; Ch: AnsiChar) of object;
  29. TScintEditDropFilesEvent = procedure(Sender: TObject; X, Y: Integer;
  30. AFiles: TStrings) of object;
  31. TScintHintInfo = Controls.THintInfo;
  32. TScintEditHintShowEvent = procedure(Sender: TObject;
  33. var Info: TScintHintInfo) of object;
  34. TScintEditMarginClickEvent = procedure(Sender: TObject; MarginNumber: Integer;
  35. Line: Integer) of object;
  36. TScintEditUpdate = (suContent, suSelection, suVScroll, suHScroll);
  37. TScintEditUpdates = set of TScintEditUpdate;
  38. TScintEditUpdateUIEvent = procedure(Sender: TObject; Updated: TScintEditUpdates) of object;
  39. TScintFindOption = (sfoMatchCase, sfoWholeWord, sfoRegEx);
  40. TScintFindOptions = set of TScintFindOption;
  41. TScintFoldFlag = (sffLineBeforeExpanded, sffLineBeforeContracted,
  42. sffLineAfterExpanded, sffLineAfterContracted, sffLevelNumbers, sffLineState);
  43. TScintFoldFlags = set of TScintFoldFlag;
  44. TScintIndentationGuides = (sigNone, sigReal, sigLookForward, sigLookBoth);
  45. TScintKeyCode = type Word;
  46. TScintKeyDefinition = type Cardinal;
  47. TScintReplaceMode = (srmNormal, srmMinimal, srmRegEx);
  48. TScintStyleByteIndicatorNumber = 0..1; { Could be increased to 0..StyleNumberUnusedBits-1 }
  49. TScintStyleByteIndicatorNumbers = set of TScintStyleByteIndicatorNumber;
  50. TScintIndicatorNumber = INDICATOR_CONTAINER..INDICATOR_MAX;
  51. TScintLineEndings = (sleCRLF, sleCR, sleLF);
  52. TScintLineState = type Integer;
  53. TScintMarkerNumber = 0..31;
  54. TScintMarkerNumbers = set of TScintMarkerNumber;
  55. TScintRange = record
  56. StartPos, EndPos: Integer;
  57. constructor Create(const AStartPos, AEndPos: Integer);
  58. function Empty: Boolean;
  59. function Overlaps(const ARange: TScintRange): Boolean;
  60. function Within(const ARange: TScintRange): Boolean;
  61. end;
  62. TScintRangeList = class(TList<TScintRange>)
  63. function Overlaps(const ARange: TScintRange;
  64. var AOverlappingRange: TScintRange): Boolean;
  65. end;
  66. TScintCaretAndAnchor = record
  67. CaretPos, AnchorPos: Integer;
  68. constructor Create(const ACaretPos, AAnchorPos: Integer);
  69. function Range: TScintRange;
  70. end;
  71. TScintCaretAndAnchorList = class(TList<TScintCaretAndAnchor>);
  72. TScintRawCharSet = set of AnsiChar;
  73. TScintRawString = type RawByteString;
  74. TScintRectangle = record
  75. Left, Top, Right, Bottom: Integer;
  76. end;
  77. TScintSelectionMode = (ssmStream, ssmRectangular, ssmLines, ssmThinRectangular);
  78. TScintStyleNumber = 0..StyleNumbers-1;
  79. TScintVirtualSpaceOption = (svsRectangularSelection, svsUserAccessible,
  80. svsNoWrapLineStart);
  81. TScintVirtualSpaceOptions = set of TScintVirtualSpaceOption;
  82. PScintRangeToFormat = ^TScintRangeToFormat;
  83. TScintRangeToFormat = record
  84. hdc, hdcTarget: UINT_PTR;
  85. rc, rcPage: TScintRectangle;
  86. chrg: TScintRange;
  87. end;
  88. TScintEditStrings = class;
  89. TScintCustomStyler = class;
  90. EScintEditError = class(Exception);
  91. TScintEdit = class(TWinControl)
  92. private
  93. FAcceptDroppedFiles: Boolean;
  94. FAutoCompleteFontName: String;
  95. FAutoCompleteFontSize: Integer;
  96. FAutoCompleteStyle: Integer;
  97. FChangeHistory: TScintChangeHistory;
  98. FCodePage: Integer;
  99. FDirectPtr: Pointer;
  100. FDirectStatusFunction: SciFnDirectStatus;
  101. FEffectiveCodePage: Integer;
  102. FEffectiveCodePageDBCS: Boolean;
  103. FFillSelectionToEdge: Boolean;
  104. FFoldLevelNumbersOrLineState: Boolean;
  105. FForceModified: Boolean;
  106. FIndentationGuides: TScintIndentationGuides;
  107. FLeadBytes: TScintRawCharSet;
  108. FLineNumbers: Boolean;
  109. FLines: TScintEditStrings;
  110. FOnAutoCompleteSelection: TScintEditAutoCompleteSelectionEvent;
  111. FOnCallTipArrowClick: TScintEditCallTipArrowClick;
  112. FOnChange: TScintEditChangeEvent;
  113. FOnCharAdded: TScintEditCharAddedEvent;
  114. FOnDropFiles: TScintEditDropFilesEvent;
  115. FOnHintShow: TScintEditHintShowEvent;
  116. FOnMarginClick: TScintEditMarginClickEvent;
  117. FOnMarginRightClick: TScintEditMarginClickEvent;
  118. FOnModifiedChange: TNotifyEvent;
  119. FOnUpdateUI: TScintEditUpdateUIEvent;
  120. FOnZoom: TNotifyEvent;
  121. FReportCaretPositionToStyler: Boolean;
  122. FStyler: TScintCustomStyler;
  123. FTabWidth: Integer;
  124. FUseStyleAttributes: Boolean;
  125. FUseTabCharacter: Boolean;
  126. FVirtualSpaceOptions: TScintVirtualSpaceOptions;
  127. FWordChars: AnsiString;
  128. FWordCharsAsSet: TSysCharSet;
  129. FWordWrap: Boolean;
  130. procedure ApplyOptions;
  131. procedure ForwardMessage(const Message: TMessage);
  132. function GetAnchorPosition: Integer;
  133. function GetAutoCompleteActive: Boolean;
  134. function GetCallTipActive: Boolean;
  135. function GetCaretColumn: Integer;
  136. function GetCaretColumnExpandedForTabs: Integer;
  137. function GetCaretLine: Integer;
  138. function GetCaretLineText: String;
  139. function GetCaretPosition: Integer;
  140. function GetCaretPositionInLine: Integer;
  141. function GetCaretVirtualSpace: Integer;
  142. function GetInsertMode: Boolean;
  143. function GetLineEndings: TScintLineEndings;
  144. function GetLineEndingString: TScintRawString;
  145. function GetLineHeight: Integer;
  146. function GetLinesInWindow: Integer;
  147. function GetMainSelText: String;
  148. function GetModified: Boolean;
  149. function GetRawCaretLineText: TScintRawString;
  150. function GetRawMainSelText: TScintRawString;
  151. function GetRawSelText: TScintRawString;
  152. function GetRawText: TScintRawString;
  153. function GetReadOnly: Boolean;
  154. class function GetReplaceTargetMessage(const ReplaceMode: TScintReplaceMode): Cardinal;
  155. class function GetSearchFlags(const Options: TScintFindOptions): Integer;
  156. function GetSelection: TScintRange;
  157. function GetSelectionAnchorPosition(Selection: Integer): Integer;
  158. function GetSelectionAnchorVirtualSpace(Selection: Integer): Integer;
  159. function GetSelectionCaretPosition(Selection: Integer): Integer;
  160. function GetSelectionCaretVirtualSpace(Selection: Integer): Integer;
  161. function GetSelectionEndPosition(Selection: Integer): Integer;
  162. function GetSelectionCount: Integer;
  163. function GetSelectionMode: TScintSelectionMode;
  164. function GetSelectionStartPosition(Selection: Integer): Integer;
  165. function GetSelText: String;
  166. function GetTopLine: Integer;
  167. function GetZoom: Integer;
  168. procedure SetAcceptDroppedFiles(const Value: Boolean);
  169. procedure SetAutoCompleteFontName(const Value: String);
  170. procedure SetAutoCompleteFontSize(const Value: Integer);
  171. procedure SetCodePage(const Value: Integer);
  172. procedure SetCaretColumn(const Value: Integer);
  173. procedure SetCaretLine(const Value: Integer);
  174. procedure SetCaretPosition(const Value: Integer);
  175. procedure SetCaretPositionWithSelectFromAnchor(const Value: Integer);
  176. procedure SetCaretVirtualSpace(const Value: Integer);
  177. procedure SetChangeHistory(const Value: TScintChangeHistory);
  178. procedure SetFillSelectionToEdge(const Value: Boolean);
  179. procedure SetFoldFlags(const Value: TScintFoldFlags);
  180. procedure SetIndentationGuides(const Value: TScintIndentationGuides);
  181. procedure SetLineNumbers(const Value: Boolean);
  182. procedure SetMainSelection(const Value: Integer);
  183. procedure SetMainSelText(const Value: String);
  184. procedure SetRawMainSelText(const Value: TScintRawString);
  185. procedure SetRawSelText(const Value: TScintRawString);
  186. procedure SetRawText(const Value: TScintRawString);
  187. procedure SetReadOnly(const Value: Boolean);
  188. procedure SetSelection(const Value: TScintRange);
  189. procedure SetSelectionAnchorPosition(Selection: Integer; const Value: Integer);
  190. procedure SetSelectionAnchorVirtualSpace(Selection: Integer;
  191. const Value: Integer);
  192. procedure SetSelectionCaretPosition(Selection: Integer; const Value: Integer);
  193. procedure SetSelectionCaretVirtualSpace(Selection: Integer;
  194. const Value: Integer);
  195. procedure SetSelectionMode(const Value: TScintSelectionMode);
  196. procedure SetSelText(const Value: String);
  197. procedure SetStyler(const Value: TScintCustomStyler);
  198. procedure SetTabWidth(const Value: Integer);
  199. procedure SetTopLine(const Value: Integer);
  200. procedure SetUseStyleAttributes(const Value: Boolean);
  201. procedure SetUseTabCharacter(const Value: Boolean);
  202. procedure SetVirtualSpaceOptions(const Value: TScintVirtualSpaceOptions);
  203. procedure SetWordWrap(const Value: Boolean);
  204. procedure SetZoom(const Value: Integer);
  205. procedure UpdateCodePage;
  206. procedure UpdateLineNumbersWidth;
  207. procedure CMColorChanged(var Message: TMessage); message CM_COLORCHANGED;
  208. procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED;
  209. procedure CMHintShow(var Message: TCMHintShow); message CM_HINTSHOW;
  210. procedure CMSysColorChange(var Message: TMessage); message CM_SYSCOLORCHANGE;
  211. procedure CNNotify(var Message: TWMNotify); message CN_NOTIFY;
  212. procedure WMDestroy(var Message: TWMDestroy); message WM_DESTROY;
  213. procedure WMDropFiles(var Message: TWMDropFiles); message WM_DROPFILES;
  214. procedure WMEraseBkgnd(var Message: TMessage); message WM_ERASEBKGND;
  215. procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;
  216. procedure WMMouseWheel(var Message: TMessage); message WM_MOUSEWHEEL;
  217. protected
  218. procedure Change(const AInserting: Boolean; const AStartPos, ALength,
  219. ALinesDelta: Integer); virtual;
  220. procedure CheckPosRange(const StartPos, EndPos: Integer);
  221. procedure CreateParams(var Params: TCreateParams); override;
  222. procedure CreateWnd; override;
  223. class function GetErrorException(const S: String): EScintEditError;
  224. class procedure Error(const S: String); overload;
  225. class procedure ErrorFmt(const S: String; const Args: array of const);
  226. function GetMainSelection: Integer;
  227. function GetTarget: TScintRange;
  228. procedure InitRawString(var S: TScintRawString; const Len: Integer);
  229. procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  230. procedure Notify(const N: TSCNotification); virtual;
  231. procedure SetTarget(const StartPos, EndPos: Integer);
  232. public
  233. constructor Create(AOwner: TComponent); override;
  234. destructor Destroy; override;
  235. procedure AddMarker(const Line: Integer; const Marker: TScintMarkerNumber);
  236. procedure AddSelection(const CaretPos, AnchorPos: Integer);
  237. procedure AssignCmdKey(const Key: AnsiChar; const Shift: TShiftState;
  238. const Command: TScintCommand); overload;
  239. procedure AssignCmdKey(const KeyCode: TScintKeyCode; const Shift: TShiftState;
  240. const Command: TScintCommand); overload;
  241. procedure BeginUndoAction;
  242. function Call(Msg: Cardinal; WParam: Longint; LParam: Longint): Longint; overload;
  243. function Call(Msg: Cardinal; WParam: Longint; LParam: Longint; out WarnStatus: Integer): Longint; overload;
  244. function Call(Msg: Cardinal; WParam: Longint; const LParamStr: TScintRawString): Longint; overload;
  245. function Call(Msg: Cardinal; WParam: Longint; const LParamStr: TScintRawString; out WarnStatus: Integer): Longint; overload;
  246. procedure CancelAutoComplete;
  247. procedure CancelAutoCompleteAndCallTip;
  248. procedure CancelCallTip;
  249. function CanPaste: Boolean;
  250. function CanRedo: Boolean;
  251. function CanUndo: Boolean;
  252. procedure ChooseCaretX;
  253. procedure ClearAll;
  254. procedure ClearCmdKey(const Key: AnsiChar; const Shift: TShiftState); overload;
  255. procedure ClearCmdKey(const KeyCode: TScintKeyCode; const Shift: TShiftState); overload;
  256. procedure ClearIndicators(const IndicatorNumber: TScintIndicatorNumber);
  257. procedure ClearSelection;
  258. procedure ClearUndo(const ClearChangeHistory: Boolean = True);
  259. function ConvertRawStringToString(const S: TScintRawString): String;
  260. function ConvertPCharToRawString(const Text: PChar;
  261. const TextLen: Integer): TScintRawString;
  262. function ConvertStringToRawString(const S: String): TScintRawString;
  263. procedure CopyToClipboard;
  264. procedure CutToClipboard;
  265. procedure DeleteAllMarkersOnLine(const Line: Integer);
  266. procedure DeleteMarker(const Line: Integer; const Marker: TScintMarkerNumber);
  267. procedure DPIChanged(const Message: TMessage);
  268. procedure EndUndoAction;
  269. procedure EnsureLineVisible(const Line: Integer);
  270. function FindRawText(const StartPos, EndPos: Integer; const S: TScintRawString;
  271. const Options: TScintFindOptions; out MatchRange: TScintRange): Boolean;
  272. function FindText(const StartPos, EndPos: Integer; const S: String;
  273. const Options: TScintFindOptions; out MatchRange: TScintRange): Boolean;
  274. procedure FoldLine(const Line: Integer; const Fold: Boolean);
  275. function FormatRange(const Draw: Boolean;
  276. const RangeToFormat: PScintRangeToFormat): Integer;
  277. procedure ForceModifiedState;
  278. function GetByteAtPosition(const Pos: Integer): AnsiChar;
  279. function GetCharacterCount(const StartPos, EndPos: Integer): Integer;
  280. function GetColumnFromPosition(const Pos: Integer): Integer;
  281. function GetDefaultWordChars: AnsiString;
  282. function GetDocLineFromVisibleLine(const VisibleLine: Integer): Integer;
  283. function GetIndicatorAtPosition(const IndicatorNumber: TScintIndicatorNumber;
  284. const Pos: Integer): Boolean;
  285. function GetLineEndPosition(const Line: Integer): Integer;
  286. function GetLineFromPosition(const Pos: Integer): Integer;
  287. function GetLineIndentation(const Line: Integer): Integer;
  288. function GetLineIndentPosition(const Line: Integer): Integer;
  289. function GetMarkers(const Line: Integer): TScintMarkerNumbers;
  290. function GetPointFromPosition(const Pos: Integer): TPoint;
  291. function GetPositionAfter(const Pos: Integer): Integer;
  292. function GetPositionBefore(const Pos: Integer): Integer;
  293. function GetPositionFromLine(const Line: Integer): Integer;
  294. function GetPositionFromLineColumn(const Line, Column: Integer): Integer;
  295. function GetPositionFromLineExpandedColumn(const Line, ExpandedColumn: Integer): Integer;
  296. function GetPositionFromPoint(const P: TPoint;
  297. const CharPosition, CloseOnly: Boolean): Integer;
  298. function GetPositionOfMatchingBrace(const Pos: Integer): Integer;
  299. function GetPositionRelative(const Pos, CharacterCount: Integer): Integer;
  300. function GetRawTextLength: Integer;
  301. function GetRawTextRange(const StartPos, EndPos: Integer): TScintRawString;
  302. procedure GetSelections(const RangeList: TScintRangeList); overload;
  303. procedure GetSelections(const CaretAndAnchorList: TScintCaretAndAnchorList); overload;
  304. procedure GetSelections(const CaretAndAnchorList, VirtualSpacesList: TScintCaretAndAnchorList); overload;
  305. function GetStyleAtPosition(const Pos: Integer): TScintStyleNumber;
  306. function GetTextRange(const StartPos, EndPos: Integer): String;
  307. function GetVisibleLineFromDocLine(const DocLine: Integer): Integer;
  308. function GetWordEndPosition(const Pos: Integer; const OnlyWordChars: Boolean): Integer;
  309. function GetWordStartPosition(const Pos: Integer; const OnlyWordChars: Boolean): Integer;
  310. function IsPositionInViewVertically(const Pos: Integer): Boolean;
  311. class function KeyCodeAndShiftToKeyDefinition(const KeyCode: TScintKeyCode;
  312. Shift: TShiftState): TScintKeyDefinition;
  313. function MainSelTextEquals(const S: String;
  314. const Options: TScintFindOptions): Boolean;
  315. class function KeyToKeyCode(const Key: AnsiChar): TScintKeyCode;
  316. procedure PasteFromClipboard;
  317. function RawMainSelTextEquals(const S: TScintRawString;
  318. const Options: TScintFindOptions): Boolean;
  319. class function RawStringIsBlank(const S: TScintRawString): Boolean;
  320. procedure Redo;
  321. procedure RemoveAdditionalSelections;
  322. function ReplaceMainSelText(const S: String;
  323. const ReplaceMode: TScintReplaceMode = srmNormal): TScintRange;
  324. function ReplaceRawMainSelText(const S: TScintRawString;
  325. const ReplaceMode: TScintReplaceMode = srmNormal): TScintRange;
  326. function ReplaceRawTextRange(const StartPos, EndPos: Integer;
  327. const S: TScintRawString; const ReplaceMode: TScintReplaceMode = srmNormal): TScintRange;
  328. function ReplaceTextRange(const StartPos, EndPos: Integer; const S: String;
  329. const ReplaceMode: TScintReplaceMode = srmNormal): TScintRange;
  330. procedure RestyleLine(const Line: Integer);
  331. procedure ScrollCaretIntoView;
  332. procedure SelectAll;
  333. procedure SelectAllOccurrences(const Options: TScintFindOptions);
  334. procedure SelectAndEnsureVisible(const Range: TScintRange);
  335. procedure SelectNextOccurrence(const Options: TScintFindOptions);
  336. function SelEmpty: Boolean;
  337. function SelNotEmpty(out Sel: TScintRange): Boolean;
  338. procedure SetAutoCompleteFillupChars(const FillupChars: AnsiString);
  339. procedure SetAutoCompleteSeparators(const Separator, TypeSeparator: AnsiChar);
  340. procedure SetAutoCompleteSelectedItem(const S: TScintRawString);
  341. procedure SetAutoCompleteStopChars(const StopChars: AnsiString);
  342. procedure SetBraceBadHighlighting(const Pos: Integer);
  343. procedure SetBraceHighlighting(const Pos1, Pos2: Integer);
  344. procedure SetCursorID(const CursorID: Integer);
  345. procedure SetCallTipHighlight(HighlightStart, HighlightEnd: Integer);
  346. procedure SetDefaultWordChars;
  347. procedure SetEmptySelection;
  348. procedure SetEmptySelections;
  349. procedure SetIndicators(const StartPos, EndPos: Integer;
  350. const IndicatorNumber: TScintIndicatorNumber; const Value: Boolean);
  351. procedure SetLineIndentation(const Line, Indentation: Integer);
  352. procedure SetSavePoint;
  353. procedure SetSingleSelection(const CaretPos, AnchorPos: Integer);
  354. procedure SettingChange(const Message: TMessage);
  355. procedure SetWordChars(const S: AnsiString);
  356. procedure ShowAutoComplete(const CharsEntered: Integer; const WordList: AnsiString);
  357. procedure ShowCallTip(const Pos: Integer; const Definition: AnsiString);
  358. procedure StyleNeeded(const EndPos: Integer);
  359. procedure SysColorChange(const Message: TMessage);
  360. function TestRegularExpression(const S: String): Boolean;
  361. function TestRawRegularExpression(const S: TScintRawString): Boolean;
  362. procedure Undo;
  363. procedure UpdateStyleAttributes;
  364. function WordAtCaret: String;
  365. function WordAtCaretRange: TScintRange;
  366. procedure ZoomIn;
  367. procedure ZoomOut;
  368. property AnchorPosition: Integer read GetAnchorPosition;
  369. property AutoCompleteActive: Boolean read GetAutoCompleteActive;
  370. property CallTipActive: Boolean read GetCallTipActive;
  371. property CaretColumn: Integer read GetCaretColumn write SetCaretColumn;
  372. property CaretColumnExpandedForTabs: Integer read GetCaretColumnExpandedForTabs;
  373. property CaretLine: Integer read GetCaretLine write SetCaretLine;
  374. property CaretLineText: String read GetCaretLineText;
  375. property CaretPosition: Integer read GetCaretPosition write SetCaretPosition;
  376. property CaretPositionInLine: Integer read GetCaretPositionInLine;
  377. property CaretPositionWithSelectFromAnchor: Integer write SetCaretPositionWithSelectFromAnchor;
  378. property CaretVirtualSpace: Integer read GetCaretVirtualSpace write SetCaretVirtualSpace;
  379. property EffectiveCodePage: Integer read FEffectiveCodePage;
  380. property FoldFlags: TScintFoldFlags write SetFoldFlags;
  381. property InsertMode: Boolean read GetInsertMode;
  382. property LineEndings: TScintLineEndings read GetLineEndings;
  383. property LineEndingString: TScintRawString read GetLineEndingString;
  384. property LineHeight: Integer read GetLineHeight;
  385. property Lines: TScintEditStrings read FLines;
  386. property LinesInWindow: Integer read GetLinesInWindow;
  387. property MainSelection: Integer read GetMainSelection write SetMainSelection;
  388. property MainSelText: String read GetMainSelText write SetMainSelText;
  389. property Modified: Boolean read GetModified;
  390. property RawCaretLineText: TScintRawString read GetRawCaretLineText;
  391. property RawMainSelText: TScintRawString read GetRawMainSelText write SetRawMainSelText;
  392. property RawSelText: TScintRawString read GetRawSelText write SetRawSelText;
  393. property RawText: TScintRawString read GetRawText write SetRawText;
  394. property RawTextLength: Integer read GetRawTextLength;
  395. property ReadOnly: Boolean read GetReadOnly write SetReadOnly;
  396. property Selection: TScintRange read GetSelection write SetSelection;
  397. property SelectionAnchorPosition[Selection: Integer]: Integer read GetSelectionAnchorPosition write SetSelectionAnchorPosition;
  398. property SelectionAnchorVirtualSpace[Selection: Integer]: Integer read GetSelectionAnchorVirtualSpace write SetSelectionAnchorVirtualSpace;
  399. property SelectionCaretPosition[Selection: Integer]: Integer read GetSelectionCaretPosition write SetSelectionCaretPosition;
  400. property SelectionCaretVirtualSpace[Selection: Integer]: Integer read GetSelectionCaretVirtualSpace write SetSelectionCaretVirtualSpace;
  401. property SelectionCount: Integer read GetSelectionCount;
  402. property SelectionEndPosition[Selection: Integer]: Integer read GetSelectionEndPosition;
  403. property SelectionMode: TScintSelectionMode read GetSelectionMode write SetSelectionMode;
  404. property SelectionStartPosition[Selection: Integer]: Integer read GetSelectionStartPosition;
  405. property SelText: String read GetSelText write SetSelText;
  406. property Styler: TScintCustomStyler read FStyler write SetStyler;
  407. property Target: TScintRange read GetTarget;
  408. property TopLine: Integer read GetTopLine write SetTopLine;
  409. property WordChars: AnsiString read FWordChars;
  410. property WordCharsAsSet: TSysCharSet read FWordCharsAsSet;
  411. published
  412. property AcceptDroppedFiles: Boolean read FAcceptDroppedFiles write SetAcceptDroppedFiles
  413. default False;
  414. property AutoCompleteFontName: String read FAutoCompleteFontName
  415. write SetAutoCompleteFontName;
  416. property AutoCompleteFontSize: Integer read FAutoCompleteFontSize
  417. write SetAutoCompleteFontSize default 0;
  418. property ChangeHistory: TScintChangeHistory read FChangeHistory write SetChangeHistory default schDisabled;
  419. property CodePage: Integer read FCodePage write SetCodePage default CP_UTF8;
  420. property Color;
  421. property FillSelectionToEdge: Boolean read FFillSelectionToEdge write SetFillSelectionToEdge
  422. default False;
  423. property Font;
  424. property IndentationGuides: TScintIndentationGuides read FIndentationGuides
  425. write SetIndentationGuides default sigNone;
  426. property LineNumbers: Boolean read FLineNumbers write SetLineNumbers default False;
  427. property ParentFont;
  428. property PopupMenu;
  429. property ReportCaretPositionToStyler: Boolean read FReportCaretPositionToStyler
  430. write FReportCaretPositionToStyler;
  431. property TabStop default True;
  432. property TabWidth: Integer read FTabWidth write SetTabWidth default 8;
  433. property UseStyleAttributes: Boolean read FUseStyleAttributes write SetUseStyleAttributes
  434. default True;
  435. property UseTabCharacter: Boolean read FUseTabCharacter write SetUseTabCharacter
  436. default True;
  437. property VirtualSpaceOptions: TScintVirtualSpaceOptions read FVirtualSpaceOptions
  438. write SetVirtualSpaceOptions default [];
  439. property WordWrap: Boolean read FWordWrap write SetWordWrap default False;
  440. property Zoom: Integer read GetZoom write SetZoom default 0;
  441. property OnAutoCompleteSelection: TScintEditAutoCompleteSelectionEvent read FOnAutoCompleteSelection write FOnAutoCompleteSelection;
  442. property OnCallTipArrowClick: TScintEditCallTipArrowClick read FOnCallTipArrowClick write FOnCallTipArrowClick;
  443. property OnChange: TScintEditChangeEvent read FOnChange write FOnChange;
  444. property OnCharAdded: TScintEditCharAddedEvent read FOnCharAdded write FOnCharAdded;
  445. property OnDropFiles: TScintEditDropFilesEvent read FOnDropFiles write FOnDropFiles;
  446. property OnHintShow: TScintEditHintShowEvent read FOnHintShow write FOnHintShow;
  447. property OnKeyDown;
  448. property OnKeyPress;
  449. property OnKeyUp;
  450. property OnMarginClick: TScintEditMarginClickEvent read FOnMarginClick write FOnMarginClick;
  451. property OnMarginRightClick: TScintEditMarginClickEvent read FOnMarginRightClick write FOnMarginRightClick;
  452. property OnModifiedChange: TNotifyEvent read FOnModifiedChange write FOnModifiedChange;
  453. property OnMouseDown;
  454. property OnMouseMove;
  455. property OnMouseUp;
  456. property OnUpdateUI: TScintEditUpdateUIEvent read FOnUpdateUI write FOnUpdateUI;
  457. property OnZoom: TNotifyEvent read FOnZoom write FOnZoom;
  458. end;
  459. TScintEditStrings = class(TStrings)
  460. private
  461. FEdit: TScintEdit;
  462. function GetLineEndingLength(const Index: Integer): Integer;
  463. function GetRawLine(Index: Integer): TScintRawString;
  464. function GetRawLineWithEnding(Index: Integer): TScintRawString;
  465. function GetRawLineLength(Index: Integer): Integer;
  466. function GetRawLineLengthWithEnding(Index: Integer): Integer;
  467. function GetState(Index: Integer): TScintLineState;
  468. procedure PutRawLine(Index: Integer; const S: TScintRawString);
  469. protected
  470. procedure CheckIndexRange(const Index: Integer);
  471. procedure CheckIndexRangePlusOne(const Index: Integer);
  472. function Get(Index: Integer): String; override;
  473. function GetCount: Integer; override;
  474. function GetTextStr: String; override;
  475. procedure Put(Index: Integer; const S: String); override;
  476. procedure SetTextStr(const Value: String); override;
  477. public
  478. procedure Clear; override;
  479. procedure Delete(Index: Integer); override;
  480. procedure Insert(Index: Integer; const S: String); override;
  481. procedure InsertRawLine(Index: Integer; const S: TScintRawString);
  482. procedure SetText(Text: PChar); override;
  483. property RawLineLengths[Index: Integer]: Integer read GetRawLineLength;
  484. property RawLineLengthsWithEnding[Index: Integer]: Integer read GetRawLineLengthWithEnding;
  485. property RawLines[Index: Integer]: TScintRawString read GetRawLine write PutRawLine;
  486. property RawLinesWithEnding[Index: Integer]: TScintRawString read GetRawLineWithEnding;
  487. property State[Index: Integer]: TScintLineState read GetState;
  488. end;
  489. TScintStyleAttributes = record
  490. FontName: String;
  491. FontSize: Integer;
  492. FontStyle: TFontStyles;
  493. FontCharset: TFontCharset;
  494. ForeColor: TColor;
  495. BackColor: TColor;
  496. end;
  497. TScintCustomStyler = class(TComponent)
  498. private
  499. FCaretIndex: Integer;
  500. FCurIndex: Integer;
  501. FLineState: TScintLineState;
  502. FStyleStartIndex: Integer;
  503. FStyleStr: AnsiString;
  504. FText: TScintRawString;
  505. FTextLen: Integer;
  506. function GetCurChar: AnsiChar;
  507. function GetEndOfLine: Boolean;
  508. protected
  509. procedure ApplyStyleByteIndicators(const Indicators: TScintStyleByteIndicatorNumbers;
  510. StartIndex, EndIndex: Integer);
  511. procedure ApplyStyle(const Style: TScintStyleNumber;
  512. StartIndex, EndIndex: Integer);
  513. procedure CommitStyle(const Style: TScintStyleNumber);
  514. function ConsumeAllRemaining: Boolean;
  515. function ConsumeChar(const C: AnsiChar): Boolean;
  516. function ConsumeCharIn(const Chars: TScintRawCharSet): Boolean;
  517. function ConsumeChars(const Chars: TScintRawCharSet): Boolean;
  518. function ConsumeCharsNot(const Chars: TScintRawCharSet): Boolean;
  519. function ConsumeString(const Chars: TScintRawCharSet): TScintRawString;
  520. function CurCharIn(const Chars: TScintRawCharSet): Boolean;
  521. function CurCharIs(const C: AnsiChar): Boolean;
  522. procedure GetFoldLevel(const LineState, PreviousLineState: TScintLineState;
  523. var Level: Integer; var Header, EnableHeaderOnPrevious: Boolean); virtual; abstract;
  524. procedure GetStyleAttributes(const Style: Integer;
  525. var Attributes: TScintStyleAttributes); virtual; abstract;
  526. function LineTextSpans(const S: TScintRawString): Boolean; virtual;
  527. function NextCharIs(const C: AnsiChar): Boolean;
  528. function PreviousCharIn(const Chars: TScintRawCharSet): Boolean;
  529. procedure ResetCurIndexTo(Index: Integer);
  530. procedure ReplaceText(StartIndex, EndIndex: Integer; const C: AnsiChar);
  531. procedure StyleNeeded; virtual; abstract;
  532. property CaretIndex: Integer read FCaretIndex;
  533. property CurChar: AnsiChar read GetCurChar;
  534. property CurIndex: Integer read FCurIndex;
  535. property EndOfLine: Boolean read GetEndOfLine;
  536. property LineState: TScintLineState read FLineState write FLineState;
  537. property StyleStartIndex: Integer read FStyleStartIndex;
  538. property Text: TScintRawString read FText;
  539. property TextLength: Integer read FTextLen;
  540. end;
  541. TScintPixmap = class
  542. private
  543. type
  544. TPixmap = array of AnsiString;
  545. class var
  546. ColorCodes: String;
  547. var
  548. FPixmap: TPixmap;
  549. class constructor Create;
  550. function GetPixmap: Pointer;
  551. public
  552. procedure InitializeFromBitmap(const ABitmap: TBitmap; const TransparentColor: TColorRef);
  553. property Pixmap: Pointer read GetPixmap;
  554. end;
  555. implementation
  556. uses
  557. ShellAPI, RTLConsts, UITypes, GraphUtil;
  558. { TScintEdit }
  559. const
  560. AUTOCSETSEPARATOR = #9;
  561. constructor TScintEdit.Create(AOwner: TComponent);
  562. begin
  563. inherited;
  564. FCodePage := CP_UTF8;
  565. FLines := TScintEditStrings.Create;
  566. FLines.FEdit := Self;
  567. FTabWidth := 8;
  568. FUseStyleAttributes := True;
  569. FUseTabCharacter := True;
  570. SetBounds(0, 0, 257, 193);
  571. ParentColor := False;
  572. TabStop := True;
  573. end;
  574. destructor TScintEdit.Destroy;
  575. begin
  576. SetStyler(nil);
  577. FLines.Free;
  578. FLines := nil;
  579. inherited;
  580. end;
  581. procedure TScintEdit.AddMarker(const Line: Integer;
  582. const Marker: TScintMarkerNumber);
  583. begin
  584. FLines.CheckIndexRange(Line);
  585. Call(SCI_MARKERADD, Line, Marker);
  586. end;
  587. procedure TScintEdit.AddSelection(const CaretPos, AnchorPos: Integer);
  588. { Adds a new selection as the main selection retaining all other selections as
  589. additional selections without scrolling the caret into view. The first
  590. selection should be added with SetSingleSelection. }
  591. begin
  592. Call(SCI_ADDSELECTION, CaretPos, AnchorPos);
  593. end;
  594. procedure TScintEdit.ApplyOptions;
  595. const
  596. IndentationGuides: array [TScintIndentationGuides] of Integer = (SC_IV_NONE, SC_IV_REAL,
  597. SC_IV_LOOKFORWARD, SC_IV_LOOKBOTH);
  598. var
  599. Flags: Integer;
  600. begin
  601. if not HandleAllocated then
  602. Exit;
  603. Call(SCI_SETSELEOLFILLED, Ord(FFillSelectionToEdge), 0);
  604. Call(SCI_SETTABWIDTH, FTabWidth, 0);
  605. Call(SCI_SETUSETABS, Ord(FUseTabCharacter), 0);
  606. Flags := 0;
  607. if svsRectangularSelection in VirtualSpaceOptions then
  608. Flags := Flags or SCVS_RECTANGULARSELECTION;
  609. if svsUserAccessible in VirtualSpaceOptions then
  610. Flags := Flags or SCVS_USERACCESSIBLE;
  611. if svsNoWrapLineStart in VirtualSpaceOptions then
  612. Flags := Flags or SCVS_NOWRAPLINESTART;
  613. Call(SCI_SETVIRTUALSPACEOPTIONS, Flags, 0);
  614. Call(SCI_SETWRAPMODE, Ord(FWordWrap), 0);
  615. Call(SCI_SETINDENTATIONGUIDES, IndentationGuides[FIndentationGuides], 0);
  616. { If FChangeHistory is not schDisabled then next call to ClearUndo will enable
  617. change history and else we should disable it now }
  618. if FChangeHistory = schDisabled then
  619. Call(SCI_SETCHANGEHISTORY, SC_CHANGE_HISTORY_DISABLED, 0);
  620. end;
  621. procedure TScintEdit.AssignCmdKey(const Key: AnsiChar; const Shift: TShiftState;
  622. const Command: TScintCommand);
  623. begin
  624. AssignCmdKey(KeyToKeyCode(Key), Shift, Command);
  625. end;
  626. procedure TScintEdit.AssignCmdKey(const KeyCode: TScintKeyCode;
  627. const Shift: TShiftState; const Command: TScintCommand);
  628. begin
  629. Call(SCI_ASSIGNCMDKEY, KeyCodeAndShiftToKeyDefinition(KeyCode, Shift), Command);
  630. end;
  631. procedure TScintEdit.BeginUndoAction;
  632. begin
  633. Call(SCI_BEGINUNDOACTION, 0, 0);
  634. end;
  635. function TScintEdit.Call(Msg: Cardinal; WParam: Longint; LParam: Longint): Longint;
  636. begin
  637. var Dummy: Integer;
  638. Result := Call(Msg, WParam, LParam, Dummy);
  639. end;
  640. function TScintEdit.Call(Msg: Cardinal; WParam: Longint; LParam: Longint;
  641. out WarnStatus: Integer): Longint;
  642. begin
  643. HandleNeeded;
  644. if FDirectPtr = nil then
  645. Error('Call: FDirectPtr is nil');
  646. if not Assigned(FDirectStatusFunction) then
  647. Error('Call: FDirectStatusFunction is nil');
  648. var ErrorStatus: Integer;
  649. Result := FDirectStatusFunction(FDirectPtr, Msg, WParam, LParam, ErrorStatus);
  650. if ErrorStatus <> 0 then begin
  651. var Dummy: Integer;
  652. FDirectStatusFunction(FDirectPtr, SCI_SETSTATUS, 0, 0, Dummy);
  653. if ErrorStatus < SC_STATUS_WARN_START then
  654. ErrorFmt('Error status %d returned after Call(%u, %d, %d) = %d',
  655. [ErrorStatus, Msg, WParam, LParam, Result]);
  656. end;
  657. WarnStatus := ErrorStatus;
  658. end;
  659. function TScintEdit.Call(Msg: Cardinal; WParam: Longint;
  660. const LParamStr: TScintRawString): Longint;
  661. begin
  662. var Dummy: Integer;
  663. Result := Call(Msg, WParam, LParamStr, Dummy);
  664. end;
  665. function TScintEdit.Call(Msg: Cardinal; WParam: Longint;
  666. const LParamStr: TScintRawString; out WarnStatus: Integer): Longint;
  667. begin
  668. Result := Call(Msg, WParam, LPARAM(PAnsiChar(LParamStr)), WarnStatus);
  669. end;
  670. procedure TScintEdit.CancelAutoComplete;
  671. begin
  672. Call(SCI_AUTOCCANCEL, 0, 0);
  673. end;
  674. procedure TScintEdit.CancelAutoCompleteAndCallTip;
  675. begin
  676. CancelAutoComplete;
  677. CancelCallTip;
  678. end;
  679. procedure TScintEdit.CancelCallTip;
  680. begin
  681. Call(SCI_CALLTIPCANCEL, 0, 0);
  682. end;
  683. function TScintEdit.CanPaste: Boolean;
  684. begin
  685. Result := Call(SCI_CANPASTE, 0, 0) <> 0;
  686. end;
  687. function TScintEdit.CanRedo: Boolean;
  688. begin
  689. Result := Call(SCI_CANREDO, 0, 0) <> 0;
  690. end;
  691. function TScintEdit.CanUndo: Boolean;
  692. begin
  693. Result := Call(SCI_CANUNDO, 0, 0) <> 0;
  694. end;
  695. procedure TScintEdit.Change(const AInserting: Boolean;
  696. const AStartPos, ALength, ALinesDelta: Integer);
  697. var
  698. Info: TScintEditChangeInfo;
  699. begin
  700. inherited Changed;
  701. if Assigned(FOnChange) then begin
  702. Info.Inserting := AInserting;
  703. Info.StartPos := AStartPos;
  704. Info.Length := ALength;
  705. Info.LinesDelta := ALinesDelta;
  706. FOnChange(Self, Info);
  707. end;
  708. end;
  709. procedure TScintEdit.CheckPosRange(const StartPos, EndPos: Integer);
  710. begin
  711. if (StartPos < 0) or (StartPos > EndPos) or (EndPos > GetRawTextLength) then
  712. ErrorFmt('CheckPosRange: Invalid range (%d, %d)', [StartPos, EndPos]);
  713. end;
  714. procedure TScintEdit.ChooseCaretX;
  715. begin
  716. Call(SCI_CHOOSECARETX, 0, 0);
  717. end;
  718. procedure TScintEdit.ClearAll;
  719. begin
  720. Call(SCI_CLEARALL, 0, 0);
  721. ChooseCaretX;
  722. end;
  723. procedure TScintEdit.ClearCmdKey(const Key: AnsiChar; const Shift: TShiftState);
  724. begin
  725. ClearCmdKey(KeyToKeyCode(Key), Shift);
  726. end;
  727. procedure TScintEdit.ClearCmdKey(const KeyCode: TScintKeyCode; const Shift: TShiftState);
  728. begin
  729. Call(SCI_CLEARCMDKEY, KeyCodeAndShiftToKeyDefinition(KeyCode, Shift), 0);
  730. end;
  731. procedure TScintEdit.ClearIndicators(
  732. const IndicatorNumber: TScintIndicatorNumber);
  733. begin
  734. Call(SCI_SETINDICATORCURRENT, IndicatorNumber, 0);
  735. Call(SCI_INDICATORCLEARRANGE, 0, RawTextLength);
  736. end;
  737. procedure TScintEdit.ClearSelection;
  738. begin
  739. Call(SCI_CLEAR, 0, 0);
  740. end;
  741. procedure TScintEdit.ClearUndo(const ClearChangeHistory: Boolean);
  742. begin
  743. { SCI_EMPTYUNDOBUFFER resets the save point but doesn't send a
  744. SCN_SAVEPOINTREACHED notification. Call SetSavePoint manually to get
  745. that. SetSavePoint additionally resets FForceModified. }
  746. SetSavePoint;
  747. Call(SCI_EMPTYUNDOBUFFER, 0, 0);
  748. { Clearing change history requires one to disable and re-enable it. But
  749. also, from Scintilla docs: "Change history depends on the undo history
  750. and can only be enabled when undo history is enabled and empty." This
  751. is why the following code is here. }
  752. if ClearChangeHistory and (FChangeHistory <> schDisabled) then begin
  753. Call(SCI_SETCHANGEHISTORY, SC_CHANGE_HISTORY_DISABLED, 0);
  754. var Flags := SC_CHANGE_HISTORY_ENABLED;
  755. if FChangeHistory = schMarkers then
  756. Flags := Flags or SC_CHANGE_HISTORY_MARKERS
  757. else
  758. Flags := Flags or SC_CHANGE_HISTORY_INDICATORS;
  759. Call(SCI_SETCHANGEHISTORY, Flags, 0);
  760. end;
  761. end;
  762. function TScintEdit.ConvertRawStringToString(const S: TScintRawString): String;
  763. var
  764. SrcLen, DestLen: Integer;
  765. DestStr: UnicodeString;
  766. begin
  767. SrcLen := Length(S);
  768. if SrcLen > 0 then begin
  769. DestLen := MultiByteToWideChar(FCodePage, 0, PAnsiChar(S), SrcLen, nil, 0);
  770. if DestLen <= 0 then
  771. Error('MultiByteToWideChar failed');
  772. SetString(DestStr, nil, DestLen);
  773. if MultiByteToWideChar(FCodePage, 0, PAnsiChar(S), SrcLen, @DestStr[1],
  774. Length(DestStr)) <> DestLen then
  775. Error('Unexpected result from MultiByteToWideChar');
  776. end;
  777. Result := DestStr;
  778. end;
  779. function TScintEdit.ConvertPCharToRawString(const Text: PChar;
  780. const TextLen: Integer): TScintRawString;
  781. var
  782. DestLen: Integer;
  783. DestStr: TScintRawString;
  784. begin
  785. if TextLen > 0 then begin
  786. DestLen := WideCharToMultiByte(FCodePage, 0, Text, TextLen, nil, 0, nil, nil);
  787. if DestLen <= 0 then
  788. Error('WideCharToMultiByte failed');
  789. InitRawString(DestStr, DestLen);
  790. if WideCharToMultiByte(FCodePage, 0, Text, TextLen, @DestStr[1], Length(DestStr),
  791. nil, nil) <> DestLen then
  792. Error('Unexpected result from WideCharToMultiByte');
  793. end;
  794. Result := DestStr;
  795. end;
  796. function TScintEdit.ConvertStringToRawString(const S: String): TScintRawString;
  797. begin
  798. Result := ConvertPCharToRawString(PChar(S), Length(S));
  799. end;
  800. procedure TScintEdit.CopyToClipboard;
  801. begin
  802. Call(SCI_COPY, 0, 0);
  803. end;
  804. procedure TScintEdit.CreateParams(var Params: TCreateParams);
  805. begin
  806. inherited;
  807. CreateSubClass(Params, 'Scintilla');
  808. //Params.ExStyle := Params.ExStyle or WS_EX_CLIENTEDGE;
  809. Params.WindowClass.style := Params.WindowClass.style and
  810. not (CS_HREDRAW or CS_VREDRAW);
  811. end;
  812. procedure TScintEdit.CreateWnd;
  813. begin
  814. if IsscintLibrary = 0 then
  815. Error('CreateWnd: IsscintLibrary is 0');
  816. inherited;
  817. FDirectPtr := Pointer(SendMessage(Handle, SCI_GETDIRECTPOINTER, 0, 0));
  818. if FDirectPtr = nil then
  819. Error('CreateWnd: FDirectPtr is nil');
  820. FDirectStatusFunction := SciFnDirectStatus(SendMessage(Handle, SCI_GETDIRECTSTATUSFUNCTION, 0, 0));
  821. if not Assigned(FDirectStatusFunction) then
  822. Error('CreateWnd: FDirectStatusFunction is nil');
  823. UpdateCodePage;
  824. Call(SCI_SETCOMMANDEVENTS, 0, 0);
  825. Call(SCI_SETMODEVENTMASK, SC_MOD_INSERTTEXT or SC_MOD_DELETETEXT, 0);
  826. Call(SCI_SETCARETPERIOD, GetCaretBlinkTime, 0);
  827. Call(SCI_SETSCROLLWIDTHTRACKING, 1, 0);
  828. { The default popup menu conflicts with the VCL's PopupMenu }
  829. Call(SCI_USEPOPUP, 0, 0);
  830. SetDefaultWordChars;
  831. ApplyOptions;
  832. UpdateStyleAttributes;
  833. if FAcceptDroppedFiles then
  834. DragAcceptFiles(Handle, True);
  835. end;
  836. procedure TScintEdit.CutToClipboard;
  837. begin
  838. Call(SCI_CUT, 0, 0);
  839. end;
  840. procedure TScintEdit.DeleteAllMarkersOnLine(const Line: Integer);
  841. begin
  842. FLines.CheckIndexRange(Line);
  843. Call(SCI_MARKERDELETE, Line, -1);
  844. end;
  845. procedure TScintEdit.DeleteMarker(const Line: Integer;
  846. const Marker: TScintMarkerNumber);
  847. begin
  848. FLines.CheckIndexRange(Line);
  849. Call(SCI_MARKERDELETE, Line, Marker);
  850. end;
  851. procedure TScintEdit.EndUndoAction;
  852. begin
  853. Call(SCI_ENDUNDOACTION, 0, 0);
  854. end;
  855. procedure TScintEdit.EnsureLineVisible(const Line: Integer);
  856. begin
  857. FLines.CheckIndexRange(Line);
  858. Call(SCI_ENSUREVISIBLE, Line, 0);
  859. end;
  860. class function TScintEdit.GetErrorException(const S: String): EScintEditError;
  861. { Can be used when just calling Error would cause a compiler warning because it doesn't realize Error always raises }
  862. begin
  863. Result := EScintEditError.Create('TScintEdit error: ' + S);
  864. end;
  865. class procedure TScintEdit.Error(const S: String);
  866. begin
  867. raise GetErrorException(S);
  868. end;
  869. class procedure TScintEdit.ErrorFmt(const S: String; const Args: array of const);
  870. begin
  871. Error(Format(S, Args));
  872. end;
  873. function TScintEdit.FindRawText(const StartPos, EndPos: Integer;
  874. const S: TScintRawString; const Options: TScintFindOptions;
  875. out MatchRange: TScintRange): Boolean;
  876. begin
  877. SetTarget(StartPos, EndPos);
  878. Call(SCI_SETSEARCHFLAGS, GetSearchFlags(Options), 0);
  879. Result := Call(SCI_SEARCHINTARGET, Length(S), S) >= 0;
  880. if Result then
  881. MatchRange := GetTarget;
  882. end;
  883. function TScintEdit.FindText(const StartPos, EndPos: Integer; const S: String;
  884. const Options: TScintFindOptions; out MatchRange: TScintRange): Boolean;
  885. begin
  886. Result := FindRawText(StartPos, EndPos, ConvertStringToRawString(S),
  887. Options, MatchRange);
  888. end;
  889. procedure TScintEdit.FoldLine(const Line: Integer; const Fold: Boolean);
  890. begin
  891. FLines.CheckIndexRange(Line);
  892. { If the line is not part of a fold the following will return False }
  893. var Folded := Call(SCI_GETFOLDEXPANDED, Line, 0) = 0;
  894. if Fold <> Folded then begin
  895. { If the line is not part of a fold the following will do nothing
  896. and else if the line is not the header Scintilla will lookup the
  897. header for us }
  898. Call(SCI_TOGGLEFOLD, Line, 0);
  899. end;
  900. end;
  901. procedure TScintEdit.ForceModifiedState;
  902. begin
  903. if not FForceModified then begin
  904. FForceModified := True;
  905. if Assigned(FOnModifiedChange) then
  906. FOnModifiedChange(Self);
  907. end;
  908. end;
  909. function TScintEdit.FormatRange(const Draw: Boolean;
  910. const RangeToFormat: PScintRangeToFormat): Integer;
  911. begin
  912. Result := Call(SCI_FORMATRANGE, Ord(Draw), LPARAM(RangeToFormat));
  913. end;
  914. procedure TScintEdit.ForwardMessage(const Message: TMessage);
  915. begin
  916. if HandleAllocated then
  917. CallWindowProc(DefWndProc, Handle, Message.Msg, Message.WParam, Message.LParam);
  918. end;
  919. function TScintEdit.GetAnchorPosition: Integer;
  920. begin
  921. Result := Call(SCI_GETANCHOR, 0, 0);
  922. end;
  923. function TScintEdit.GetAutoCompleteActive: Boolean;
  924. begin
  925. Result := Call(SCI_AUTOCACTIVE, 0, 0) <> 0;
  926. end;
  927. function TScintEdit.GetByteAtPosition(const Pos: Integer): AnsiChar;
  928. begin
  929. Result := AnsiChar(Call(SCI_GETCHARAT, Pos, 0));
  930. end;
  931. function TScintEdit.GetCallTipActive: Boolean;
  932. begin
  933. Result := Call(SCI_CALLTIPACTIVE, 0, 0) <> 0;
  934. end;
  935. function TScintEdit.GetCaretColumn: Integer;
  936. begin
  937. Result := GetColumnFromPosition(GetCaretPosition);
  938. end;
  939. function TScintEdit.GetCaretColumnExpandedForTabs: Integer;
  940. begin
  941. Result := Call(SCI_GETCOLUMN, GetCaretPosition, 0);
  942. Inc(Result, GetCaretVirtualSpace);
  943. end;
  944. function TScintEdit.GetCaretLine: Integer;
  945. begin
  946. Result := GetLineFromPosition(GetCaretPosition);
  947. end;
  948. function TScintEdit.GetCaretLineText: String;
  949. begin
  950. Result := ConvertRawStringToString(GetRawCaretLineText);
  951. end;
  952. function TScintEdit.GetCaretPosition: Integer;
  953. begin
  954. Result := Call(SCI_GETCURRENTPOS, 0, 0);
  955. end;
  956. function TScintEdit.GetCaretPositionInLine: Integer;
  957. begin
  958. var Caret := CaretPosition;
  959. var LineStart := GetPositionFromLine(GetLineFromPosition(Caret));
  960. Result := Caret - LineStart;
  961. end;
  962. function TScintEdit.GetCaretVirtualSpace: Integer;
  963. begin
  964. Result := GetSelectionCaretVirtualSpace(GetMainSelection);
  965. end;
  966. function TScintEdit.GetCharacterCount(const StartPos, EndPos: Integer): Integer;
  967. begin
  968. CheckPosRange(StartPos, EndPos);
  969. Result := Call(SCI_COUNTCHARACTERS, StartPos, EndPos);
  970. end;
  971. function TScintEdit.GetColumnFromPosition(const Pos: Integer): Integer;
  972. var
  973. Line: Integer;
  974. begin
  975. Line := GetLineFromPosition(Pos);
  976. Result := Pos - GetPositionFromLine(Line);
  977. end;
  978. function TScintEdit.GetDefaultWordChars: AnsiString;
  979. begin
  980. Result := 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_';
  981. end;
  982. function TScintEdit.GetDocLineFromVisibleLine(const VisibleLine: Integer): Integer;
  983. begin
  984. Result := Call(SCI_DOCLINEFROMVISIBLE, VisibleLine, 0);
  985. end;
  986. function TScintEdit.GetIndicatorAtPosition(
  987. const IndicatorNumber: TScintIndicatorNumber; const Pos: Integer): Boolean;
  988. begin
  989. Result := Call(SCI_INDICATORVALUEAT, IndicatorNumber, Pos) <> 0;
  990. end;
  991. function TScintEdit.GetInsertMode: Boolean;
  992. begin
  993. Result := Call(SCI_GETOVERTYPE, 0, 0) = 0;
  994. end;
  995. function TScintEdit.GetLineEndings: TScintLineEndings;
  996. begin
  997. case Call(SCI_GETEOLMODE, 0, 0) of
  998. SC_EOL_CR: Result := sleCR;
  999. SC_EOL_LF: Result := sleLF;
  1000. SC_EOL_CRLF: Result := sleCRLF;
  1001. else
  1002. raise GetErrorException('Unexpected SCI_GETEOLMODE result');
  1003. end;
  1004. end;
  1005. function TScintEdit.GetLineEndingString: TScintRawString;
  1006. const
  1007. EndingStrs: array[TScintLineEndings] of TScintRawString =
  1008. (#13#10, #13, #10);
  1009. begin
  1010. Result := EndingStrs[LineEndings];
  1011. end;
  1012. function TScintEdit.GetLineEndPosition(const Line: Integer): Integer;
  1013. { Returns the position at the end of the line, before any line end characters. }
  1014. begin
  1015. FLines.CheckIndexRange(Line);
  1016. Result := Call(SCI_GETLINEENDPOSITION, Line, 0);
  1017. end;
  1018. function TScintEdit.GetLineFromPosition(const Pos: Integer): Integer;
  1019. begin
  1020. Result := Call(SCI_LINEFROMPOSITION, Pos, 0);
  1021. end;
  1022. function TScintEdit.GetLineHeight: Integer;
  1023. begin
  1024. Result := Call(SCI_TEXTHEIGHT, 0, 0);
  1025. end;
  1026. function TScintEdit.GetLineIndentation(const Line: Integer): Integer;
  1027. begin
  1028. FLines.CheckIndexRange(Line);
  1029. Result := Call(SCI_GETLINEINDENTATION, Line, 0);
  1030. end;
  1031. function TScintEdit.GetLineIndentPosition(const Line: Integer): Integer;
  1032. begin
  1033. FLines.CheckIndexRange(Line);
  1034. Result := Call(SCI_GETLINEINDENTPOSITION, Line, 0);
  1035. end;
  1036. function TScintEdit.GetLinesInWindow: Integer;
  1037. begin
  1038. Result := Call(SCI_LINESONSCREEN, 0, 0);
  1039. end;
  1040. function TScintEdit.GetMainSelection: Integer;
  1041. begin
  1042. Result := Call(SCI_GETMAINSELECTION, 0, 0);
  1043. end;
  1044. function TScintEdit.GetMainSelText: String;
  1045. begin
  1046. Result := ConvertRawStringToString(GetRawMainSelText);
  1047. end;
  1048. function TScintEdit.GetMarkers(const Line: Integer): TScintMarkerNumbers;
  1049. begin
  1050. FLines.CheckIndexRange(Line);
  1051. Integer(Result) := Call(SCI_MARKERGET, Line, 0);
  1052. end;
  1053. function TScintEdit.GetModified: Boolean;
  1054. begin
  1055. Result := FForceModified or (Call(SCI_GETMODIFY, 0, 0) <> 0);
  1056. end;
  1057. function TScintEdit.GetPointFromPosition(const Pos: Integer): TPoint;
  1058. begin
  1059. Result.X := Call(SCI_POINTXFROMPOSITION, 0, Pos);
  1060. Result.Y := Call(SCI_POINTYFROMPOSITION, 0, Pos);
  1061. end;
  1062. function TScintEdit.GetPositionAfter(const Pos: Integer): Integer;
  1063. begin
  1064. Result := Call(SCI_POSITIONAFTER, Pos, 0);
  1065. end;
  1066. function TScintEdit.GetPositionBefore(const Pos: Integer): Integer;
  1067. begin
  1068. Result := Call(SCI_POSITIONBEFORE, Pos, 0);
  1069. end;
  1070. function TScintEdit.GetPositionFromLine(const Line: Integer): Integer;
  1071. begin
  1072. FLines.CheckIndexRangePlusOne(Line);
  1073. Result := Call(SCI_POSITIONFROMLINE, Line, 0);
  1074. end;
  1075. function TScintEdit.GetPositionFromLineColumn(const Line, Column: Integer): Integer;
  1076. var
  1077. Col, Len: Integer;
  1078. begin
  1079. Col := Column;
  1080. Result := GetPositionFromLine(Line);
  1081. Len := GetLineEndPosition(Line) - Result;
  1082. if Col > Len then
  1083. Col := Len;
  1084. if Col > 0 then
  1085. Inc(Result, Col);
  1086. end;
  1087. function TScintEdit.GetPositionFromLineExpandedColumn(const Line,
  1088. ExpandedColumn: Integer): Integer;
  1089. begin
  1090. FLines.CheckIndexRange(Line);
  1091. Result := Call(SCI_FINDCOLUMN, Line, ExpandedColumn);
  1092. end;
  1093. function TScintEdit.GetPositionFromPoint(const P: TPoint;
  1094. const CharPosition, CloseOnly: Boolean): Integer;
  1095. begin
  1096. if CharPosition then begin
  1097. if CloseOnly then
  1098. Result := Call(SCI_CHARPOSITIONFROMPOINTCLOSE, P.X, P.Y)
  1099. else
  1100. Result := Call(SCI_CHARPOSITIONFROMPOINT, P.X, P.Y);
  1101. end
  1102. else begin
  1103. if CloseOnly then
  1104. Result := Call(SCI_POSITIONFROMPOINTCLOSE, P.X, P.Y)
  1105. else
  1106. Result := Call(SCI_POSITIONFROMPOINT, P.X, P.Y);
  1107. end;
  1108. end;
  1109. function TScintEdit.GetPositionOfMatchingBrace(const Pos: Integer): Integer;
  1110. begin
  1111. Result := Call(SCI_BRACEMATCH, Pos, 0);
  1112. end;
  1113. function TScintEdit.GetPositionRelative(const Pos,
  1114. CharacterCount: Integer): Integer;
  1115. begin
  1116. Result := Call(SCI_POSITIONRELATIVE, Pos, CharacterCount);
  1117. end;
  1118. function TScintEdit.GetRawCaretLineText: TScintRawString;
  1119. begin
  1120. var Line := CaretLine;
  1121. Result := GetRawTextRange(GetPositionFromLine(Line), GetPositionFromLine(Line+1));
  1122. end;
  1123. function TScintEdit.GetRawMainSelText: TScintRawString;
  1124. begin
  1125. var MainSel := MainSelection;
  1126. var CaretPos := SelectionCaretPosition[MainSel];
  1127. var AnchorPos := SelectionAnchorPosition[MainSel];
  1128. if AnchorPos < CaretPos then
  1129. Result := GetRawTextRange(AnchorPos, CaretPos)
  1130. else
  1131. Result := GetRawTextRange(CaretPos, AnchorPos);
  1132. end;
  1133. function TScintEdit.GetRawSelText: TScintRawString;
  1134. { Gets the combined text of *all* selections }
  1135. var
  1136. Len: Integer;
  1137. S: TScintRawString;
  1138. begin
  1139. Len := Call(SCI_GETSELTEXT, 0, 0);
  1140. if Len > 0 then begin
  1141. InitRawString(S, Len);
  1142. Call(SCI_GETSELTEXT, 0, LPARAM(PAnsiChar(@S[1])));
  1143. end;
  1144. Result := S;
  1145. end;
  1146. function TScintEdit.GetRawText: TScintRawString;
  1147. begin
  1148. Result := GetRawTextRange(0, GetRawTextLength);
  1149. end;
  1150. function TScintEdit.GetRawTextLength: Integer;
  1151. begin
  1152. Result := Call(SCI_GETLENGTH, 0, 0);
  1153. end;
  1154. function TScintEdit.GetRawTextRange(const StartPos, EndPos: Integer): TScintRawString;
  1155. var
  1156. S: TScintRawString;
  1157. Range: TSci_TextRange;
  1158. begin
  1159. CheckPosRange(StartPos, EndPos);
  1160. if EndPos > StartPos then begin
  1161. InitRawString(S, EndPos - StartPos);
  1162. Range.chrg.cpMin := StartPos;
  1163. Range.chrg.cpMax := EndPos;
  1164. Range.lpstrText := @S[1];
  1165. if Call(SCI_GETTEXTRANGE, 0, LPARAM(@Range)) <> EndPos - StartPos then
  1166. Error('Unexpected result from SCI_GETTEXTRANGE');
  1167. end;
  1168. Result := S;
  1169. end;
  1170. function TScintEdit.GetReadOnly: Boolean;
  1171. begin
  1172. Result := Call(SCI_GETREADONLY, 0, 0) <> 0;
  1173. end;
  1174. class function TScintEdit.GetReplaceTargetMessage(
  1175. const ReplaceMode: TScintReplaceMode): Cardinal;
  1176. begin
  1177. case ReplaceMode of
  1178. srmNormal: Result := SCI_REPLACETARGET;
  1179. srmMinimal: Result := SCI_REPLACETARGETMINIMAL;
  1180. srmRegEx: Result := SCI_REPLACETARGETRE;
  1181. else
  1182. raise GetErrorException('Unknown ReplaceMode');
  1183. end;
  1184. end;
  1185. class function TScintEdit.GetSearchFlags(const Options: TScintFindOptions): Integer;
  1186. begin
  1187. { Note: Scintilla ignores SCFIND_WHOLEWORD when SCFIND_REGEXP is set }
  1188. Result := 0;
  1189. if sfoMatchCase in Options then
  1190. Result := Result or SCFIND_MATCHCASE;
  1191. if sfoWholeWord in Options then
  1192. Result := Result or SCFIND_WHOLEWORD;
  1193. if sfoRegEx in Options then
  1194. Result := Result or (SCFIND_REGEXP or SCFIND_CXX11REGEX);
  1195. end;
  1196. function TScintEdit.GetSelection: TScintRange;
  1197. begin
  1198. Result.StartPos := Call(SCI_GETSELECTIONSTART, 0, 0);
  1199. Result.EndPos := Call(SCI_GETSELECTIONEND, 0, 0);
  1200. end;
  1201. procedure TScintEdit.GetSelections(const RangeList: TScintRangeList);
  1202. begin
  1203. RangeList.Clear;
  1204. for var I := 0 to SelectionCount-1 do begin
  1205. var StartPos := GetSelectionStartPosition(I);
  1206. var EndPos := GetSelectionEndPosition(I);
  1207. RangeList.Add(TScintRange.Create(StartPos, EndPos));
  1208. end;
  1209. end;
  1210. procedure TScintEdit.GetSelections(const CaretAndAnchorList: TScintCaretAndAnchorList);
  1211. begin
  1212. CaretAndAnchorList.Clear;
  1213. for var I := 0 to SelectionCount-1 do begin
  1214. var CaretPos := GetSelectionCaretPosition(I);
  1215. var AnchorPos := GetSelectionAnchorPosition(I);
  1216. CaretAndAnchorList.Add(TScintCaretAndAnchor.Create(CaretPos, AnchorPos));
  1217. end;
  1218. end;
  1219. procedure TScintEdit.GetSelections(const CaretAndAnchorList, VirtualSpacesList: TScintCaretAndAnchorList);
  1220. begin
  1221. GetSelections(CaretAndAnchorList);
  1222. VirtualSpacesList.Clear;
  1223. for var I := 0 to SelectionCount-1 do begin
  1224. var CaretPos := GetSelectionCaretVirtualSpace(I);
  1225. var AnchorPos := GetSelectionAnchorVirtualSpace(I);
  1226. VirtualSpacesList.Add(TScintCaretAndAnchor.Create(CaretPos, AnchorPos));
  1227. end;
  1228. end;
  1229. function TScintEdit.GetSelectionAnchorPosition(Selection: Integer): Integer;
  1230. begin
  1231. Result := Call(SCI_GETSELECTIONNANCHOR, Selection, 0);
  1232. end;
  1233. function TScintEdit.GetSelectionAnchorVirtualSpace(Selection: Integer): Integer;
  1234. begin
  1235. Result := Call(SCI_GETSELECTIONNANCHORVIRTUALSPACE, Selection, 0);
  1236. end;
  1237. function TScintEdit.GetSelectionCaretPosition(Selection: Integer): Integer;
  1238. begin
  1239. Result := Call(SCI_GETSELECTIONNCARET, Selection, 0);
  1240. end;
  1241. function TScintEdit.GetSelectionCaretVirtualSpace(Selection: Integer): Integer;
  1242. begin
  1243. Result := Call(SCI_GETSELECTIONNCARETVIRTUALSPACE, Selection, 0);
  1244. end;
  1245. function TScintEdit.GetSelectionCount: Integer;
  1246. { Returns the number of selections currently active. Rectangular selections are
  1247. handled (and returned) as multiple selections, one for each line. }
  1248. begin
  1249. Result := Call(SCI_GETSELECTIONS, 0, 0);
  1250. end;
  1251. function TScintEdit.GetSelectionEndPosition(Selection: Integer): Integer;
  1252. begin
  1253. Result := Call(SCI_GETSELECTIONNEND, Selection, 0)
  1254. end;
  1255. function TScintEdit.GetSelectionMode: TScintSelectionMode;
  1256. begin
  1257. case Call(SCI_GETSELECTIONMODE, 0, 0) of
  1258. SC_SEL_STREAM: Result := ssmStream;
  1259. SC_SEL_RECTANGLE: Result := ssmRectangular;
  1260. SC_SEL_LINES: Result := ssmLines;
  1261. SC_SEL_THIN: Result := ssmThinRectangular;
  1262. else
  1263. raise GetErrorException('Unexpected SCI_GETSELECTIONMODE result');
  1264. end;
  1265. end;
  1266. function TScintEdit.GetSelectionStartPosition(Selection: Integer): Integer;
  1267. begin
  1268. Result := Call(SCI_GETSELECTIONNSTART, Selection, 0);
  1269. end;
  1270. function TScintEdit.GetSelText: String;
  1271. begin
  1272. Result := ConvertRawStringToString(GetRawSelText);
  1273. end;
  1274. function TScintEdit.GetStyleAtPosition(const Pos: Integer): TScintStyleNumber;
  1275. begin
  1276. Result := Call(SCI_GETSTYLEAT, Pos, 0);
  1277. end;
  1278. function TScintEdit.GetTarget: TScintRange;
  1279. begin
  1280. Result.StartPos := Call(SCI_GETTARGETSTART, 0, 0);
  1281. Result.EndPos := Call(SCI_GETTARGETEND, 0, 0);
  1282. end;
  1283. function TScintEdit.GetTextRange(const StartPos, EndPos: Integer): String;
  1284. begin
  1285. Result := ConvertRawStringToString(GetRawTextRange(StartPos, EndPos));
  1286. end;
  1287. function TScintEdit.GetTopLine: Integer;
  1288. begin
  1289. Result := Call(SCI_GETFIRSTVISIBLELINE, 0, 0);
  1290. end;
  1291. function TScintEdit.GetVisibleLineFromDocLine(const DocLine: Integer): Integer;
  1292. begin
  1293. FLines.CheckIndexRange(DocLine);
  1294. Result := Call(SCI_VISIBLEFROMDOCLINE, DocLine, 0);
  1295. end;
  1296. function TScintEdit.GetWordEndPosition(const Pos: Integer;
  1297. const OnlyWordChars: Boolean): Integer;
  1298. begin
  1299. Result := Call(SCI_WORDENDPOSITION, Pos, Ord(OnlyWordChars));
  1300. end;
  1301. function TScintEdit.GetWordStartPosition(const Pos: Integer;
  1302. const OnlyWordChars: Boolean): Integer;
  1303. begin
  1304. Result := Call(SCI_WORDSTARTPOSITION, Pos, Ord(OnlyWordChars));
  1305. end;
  1306. function TScintEdit.GetZoom: Integer;
  1307. begin
  1308. Result := Call(SCI_GETZOOM, 0, 0);
  1309. end;
  1310. procedure TScintEdit.InitRawString(var S: TScintRawString; const Len: Integer);
  1311. begin
  1312. SetString(S, nil, Len);
  1313. //experimental, dont need this ATM:
  1314. if FCodePage <> 0 then
  1315. System.SetCodePage(RawByteString(S), FCodePage, False);
  1316. end;
  1317. function TScintEdit.IsPositionInViewVertically(const Pos: Integer): Boolean;
  1318. var
  1319. P: TPoint;
  1320. begin
  1321. P := GetPointFromPosition(Pos);
  1322. Result := (P.Y >= 0) and (P.Y + GetLineHeight <= ClientHeight);
  1323. end;
  1324. class function TScintEdit.KeyCodeAndShiftToKeyDefinition(
  1325. const KeyCode: TScintKeyCode; Shift: TShiftState): TScintKeyDefinition;
  1326. begin
  1327. Result := KeyCode;
  1328. if ssShift in Shift then
  1329. Result := Result or (SCMOD_SHIFT shl 16);
  1330. if ssAlt in Shift then
  1331. Result := Result or (SCMOD_ALT shl 16);
  1332. if ssCtrl in Shift then
  1333. Result := Result or (SCMOD_CTRL shl 16);
  1334. end;
  1335. class function TScintEdit.KeyToKeyCode(const Key: AnsiChar): TScintKeyCode;
  1336. begin
  1337. Result := Ord(UpCase(Key));
  1338. end;
  1339. function TScintEdit.MainSelTextEquals(const S: String;
  1340. const Options: TScintFindOptions): Boolean;
  1341. begin
  1342. Result := RawMainSelTextEquals(ConvertStringToRawString(S), Options);
  1343. end;
  1344. procedure TScintEdit.Notification(AComponent: TComponent; Operation: TOperation);
  1345. begin
  1346. inherited;
  1347. if Operation = opRemove then
  1348. if AComponent = FStyler then
  1349. SetStyler(nil);
  1350. end;
  1351. procedure TScintEdit.Notify(const N: TSCNotification);
  1352. begin
  1353. case N.nmhdr.code of
  1354. SCN_AUTOCSELECTION:
  1355. begin
  1356. if Assigned(FOnAutoCompleteSelection) then
  1357. FOnAutoCompleteSelection(Self);
  1358. end;
  1359. SCN_CALLTIPCLICK:
  1360. begin
  1361. if (N.position in [1, 2]) and Assigned(FOnCallTipArrowClick) then
  1362. FOnCallTipArrowClick(Self, N.position = 1);
  1363. end;
  1364. SCN_CHARADDED:
  1365. begin
  1366. if Assigned(FOnCharAdded) then
  1367. FOnCharAdded(Self, AnsiChar(N.ch));
  1368. end;
  1369. SCN_MARGINCLICK:
  1370. begin
  1371. if Assigned(FOnMarginClick) then
  1372. FOnMarginClick(Self, N.margin, GetLineFromPosition(N.position));
  1373. end;
  1374. SCN_MARGINRIGHTCLICK:
  1375. begin
  1376. if Assigned(FOnMarginRightClick) then
  1377. FOnMarginRightClick(Self, N.margin, GetLineFromPosition(N.position));
  1378. end;
  1379. SCN_MODIFIED:
  1380. begin
  1381. { CreateWnd limits SCN_MODIFIED to INSERTTEXT and DELETETEXT }
  1382. if N.modificationType and SC_MOD_INSERTTEXT <> 0 then
  1383. Change(True, N.position, N.length, N.linesAdded)
  1384. else if N.modificationType and SC_MOD_DELETETEXT <> 0 then
  1385. Change(False, N.position, N.length, N.linesAdded);
  1386. if (N.linesAdded > 0) and FLineNumbers then
  1387. UpdateLineNumbersWidth;
  1388. end;
  1389. SCN_SAVEPOINTLEFT,
  1390. SCN_SAVEPOINTREACHED:
  1391. begin
  1392. if Assigned(FOnModifiedChange) then
  1393. FOnModifiedChange(Self);
  1394. end;
  1395. SCN_STYLENEEDED: StyleNeeded(N.position);
  1396. SCN_UPDATEUI:
  1397. begin
  1398. if Assigned(FOnUpdateUI) then
  1399. FOnUpdateUI(Self, TScintEditUpdates(Byte(N.updated)));
  1400. end;
  1401. SCN_ZOOM:
  1402. begin
  1403. if Assigned(FOnZoom) then
  1404. FOnZoom(Self);
  1405. if FLineNumbers then
  1406. UpdateLineNumbersWidth;
  1407. end;
  1408. end;
  1409. end;
  1410. procedure TScintEdit.PasteFromClipboard;
  1411. begin
  1412. Call(SCI_PASTE, 0, 0);
  1413. end;
  1414. function TScintEdit.RawMainSelTextEquals(const S: TScintRawString;
  1415. const Options: TScintFindOptions): Boolean;
  1416. begin
  1417. Call(SCI_TARGETFROMSELECTION, 0, 0);
  1418. Call(SCI_SETSEARCHFLAGS, GetSearchFlags(Options), 0);
  1419. Result := False;
  1420. if Call(SCI_SEARCHINTARGET, Length(S), S) >= 0 then begin
  1421. var Target := GetTarget;
  1422. var Sel := GetSelection;
  1423. if (Target.StartPos = Sel.StartPos) and (Target.EndPos = Sel.EndPos) then
  1424. Result := True;
  1425. end;
  1426. end;
  1427. class function TScintEdit.RawStringIsBlank(const S: TScintRawString): Boolean;
  1428. begin
  1429. for var I := 1 to Length(S) do
  1430. if not(S[I] in [#9, ' ']) then
  1431. Exit(False);
  1432. Result := True;
  1433. end;
  1434. procedure TScintEdit.Redo;
  1435. begin
  1436. Call(SCI_REDO, 0, 0);
  1437. end;
  1438. procedure TScintEdit.RemoveAdditionalSelections;
  1439. { Removes additional selections without scrolling the caret into view }
  1440. begin
  1441. var MainSel := MainSelection;
  1442. var CaretPos := SelectionCaretPosition[MainSel];
  1443. var AnchorPos := SelectionAnchorPosition[MainSel];
  1444. SetSingleSelection(CaretPos, AnchorPos);
  1445. end;
  1446. function TScintEdit.ReplaceMainSelText(const S: String;
  1447. const ReplaceMode: TScintReplaceMode): TScintRange;
  1448. begin
  1449. ReplaceRawMainSelText(ConvertStringToRawString(S), ReplaceMode);
  1450. end;
  1451. function TScintEdit.ReplaceRawMainSelText(const S: TScintRawString;
  1452. const ReplaceMode: TScintReplaceMode): TScintRange;
  1453. { Replaces the main selection just like SetRawSelText/SCI_REPLACESEL but
  1454. without removing additional selections }
  1455. begin
  1456. { First replace the selection }
  1457. Call(SCI_TARGETFROMSELECTION, 0, 0);
  1458. Call(GetReplaceTargetMessage(ReplaceMode), Length(S), S);
  1459. { Then make the main selection an empty selection at the end of the inserted
  1460. text, just like SCI_REPLACESEL }
  1461. var Pos := GetTarget.EndPos; { SCI_REPLACETARGET* updates the target }
  1462. var MainSel := MainSelection;
  1463. SetSelectionCaretPosition(MainSel, Pos);
  1464. SetSelectionAnchorPosition(MainSel, Pos);
  1465. { Finally call Editor::SetLastXChosen and scroll caret into view, also just
  1466. like SCI_REPLACESEL }
  1467. ChooseCaretX;
  1468. ScrollCaretIntoView;
  1469. end;
  1470. function TScintEdit.ReplaceRawTextRange(const StartPos, EndPos: Integer;
  1471. const S: TScintRawString; const ReplaceMode: TScintReplaceMode): TScintRange;
  1472. begin
  1473. CheckPosRange(StartPos, EndPos);
  1474. SetTarget(StartPos, EndPos);
  1475. Call(GetReplaceTargetMessage(ReplaceMode), Length(S), S);
  1476. Result := GetTarget;
  1477. end;
  1478. function TScintEdit.ReplaceTextRange(const StartPos, EndPos: Integer;
  1479. const S: String; const ReplaceMode: TScintReplaceMode): TScintRange;
  1480. begin
  1481. Result := ReplaceRawTextRange(StartPos, EndPos, ConvertStringToRawString(S), ReplaceMode);
  1482. end;
  1483. procedure TScintEdit.RestyleLine(const Line: Integer);
  1484. begin
  1485. var StartPos := GetPositionFromLine(Line);
  1486. var EndPos := GetPositionFromLine(Line + 1);
  1487. { Back up the 'last styled position' if necessary using SCI_STARTSTYLINE
  1488. (SCI_SETENDSTYLED would have been a clearer name because setting the
  1489. 'last styled position' is all it does) }
  1490. if StartPos < Call(SCI_GETENDSTYLED, 0, 0) then
  1491. Call(SCI_STARTSTYLING, StartPos, 0);
  1492. StyleNeeded(EndPos);
  1493. end;
  1494. procedure TScintEdit.ScrollCaretIntoView;
  1495. begin
  1496. Call(SCI_SCROLLCARET, 0, 0);
  1497. end;
  1498. procedure TScintEdit.SelectAllOccurrences(const Options: TScintFindOptions);
  1499. { At the moment this does not automatically expand folds, unlike VSCode. Also
  1500. see SelectNextOccurrence. }
  1501. begin
  1502. Call(SCI_TARGETWHOLEDOCUMENT, 0, 0);
  1503. Call(SCI_SETSEARCHFLAGS, GetSearchFlags(Options), 0);
  1504. Call(SCI_MULTIPLESELECTADDEACH, 0, 0);
  1505. end;
  1506. procedure TScintEdit.SelectAndEnsureVisible(const Range: TScintRange);
  1507. begin
  1508. CheckPosRange(Range.StartPos, Range.EndPos);
  1509. { If the range is in a contracted section, expand it }
  1510. var StartLine := GetLineFromPosition(Range.StartPos);
  1511. var EndLine := GetLineFromPosition(Range.EndPos);
  1512. for var Line := StartLine to EndLine do
  1513. EnsureLineVisible(Line);
  1514. { Select }
  1515. Selection := Range;
  1516. end;
  1517. procedure TScintEdit.SelectNextOccurrence(const Options: TScintFindOptions);
  1518. { At the moment this does not automatically expand folds, unlike VSCode. Also
  1519. see SelectAllOccurrences. }
  1520. begin
  1521. Call(SCI_TARGETWHOLEDOCUMENT, 0, 0);
  1522. Call(SCI_SETSEARCHFLAGS, GetSearchFlags(Options), 0);
  1523. Call(SCI_MULTIPLESELECTADDNEXT, 0, 0);
  1524. end;
  1525. function TScintEdit.SelEmpty: Boolean;
  1526. { Returns True if the main selection is empty even if there are additional
  1527. selections. }
  1528. begin
  1529. var Sel: TScintRange;
  1530. Result := not SelNotEmpty(Sel);
  1531. end;
  1532. function TScintEdit.SelNotEmpty(out Sel: TScintRange): Boolean;
  1533. begin
  1534. Sel := GetSelection;
  1535. Result := Sel.EndPos > Sel.StartPos;
  1536. end;
  1537. procedure TScintEdit.SelectAll;
  1538. begin
  1539. Call(SCI_SELECTALL, 0, 0);
  1540. end;
  1541. procedure TScintEdit.SetAcceptDroppedFiles(const Value: Boolean);
  1542. begin
  1543. if FAcceptDroppedFiles <> Value then begin
  1544. FAcceptDroppedFiles := Value;
  1545. if HandleAllocated then
  1546. DragAcceptFiles(Handle, Value);
  1547. end;
  1548. end;
  1549. procedure TScintEdit.SetAutoCompleteFillupChars(const FillupChars: AnsiString);
  1550. begin
  1551. Call(SCI_AUTOCSETFILLUPS, 0, FillupChars);
  1552. end;
  1553. procedure TScintEdit.SetAutoCompleteFontName(const Value: String);
  1554. begin
  1555. if FAutoCompleteFontName <> Value then begin
  1556. FAutoCompleteFontName := Value;
  1557. UpdateStyleAttributes;
  1558. end;
  1559. end;
  1560. procedure TScintEdit.SetAutoCompleteFontSize(const Value: Integer);
  1561. begin
  1562. if FAutoCompleteFontSize <> Value then begin
  1563. FAutoCompleteFontSize := Value;
  1564. UpdateStyleAttributes;
  1565. end;
  1566. end;
  1567. procedure TScintEdit.SetAutoCompleteSelectedItem(const S: TScintRawString);
  1568. begin
  1569. Call(SCI_AUTOCSELECT, 0, S);
  1570. end;
  1571. procedure TScintEdit.SetAutoCompleteSeparators(const Separator, TypeSeparator: AnsiChar);
  1572. begin
  1573. Call(SCI_AUTOCSETSEPARATOR, WParam(Separator), 0);
  1574. Call(SCI_AUTOCSETTYPESEPARATOR, WParam(TypeSeparator), 0);
  1575. end;
  1576. procedure TScintEdit.SetAutoCompleteStopChars(const StopChars: AnsiString);
  1577. begin
  1578. Call(SCI_AUTOCSTOPS, 0, StopChars);
  1579. end;
  1580. procedure TScintEdit.SetBraceBadHighlighting(const Pos: Integer);
  1581. begin
  1582. Call(SCI_BRACEBADLIGHT, Pos, 0);
  1583. end;
  1584. procedure TScintEdit.SetBraceHighlighting(const Pos1, Pos2: Integer);
  1585. begin
  1586. Call(SCI_BRACEHIGHLIGHT, Pos1, Pos2);
  1587. end;
  1588. procedure TScintEdit.SetCallTipHighlight(HighlightStart, HighlightEnd: Integer);
  1589. begin
  1590. Call(SCI_CALLTIPSETHLT, HighlightStart, HighlightEnd);
  1591. end;
  1592. procedure TScintEdit.SetCaretColumn(const Value: Integer);
  1593. begin
  1594. SetCaretPosition(GetPositionFromLineColumn(GetCaretLine, Value));
  1595. end;
  1596. procedure TScintEdit.SetCaretLine(const Value: Integer);
  1597. begin
  1598. Call(SCI_GOTOLINE, Value, 0);
  1599. ChooseCaretX;
  1600. end;
  1601. procedure TScintEdit.SetCaretPosition(const Value: Integer);
  1602. begin
  1603. Call(SCI_GOTOPOS, Value, 0);
  1604. ChooseCaretX;
  1605. end;
  1606. procedure TScintEdit.SetCaretPositionWithSelectFromAnchor(const Value: Integer);
  1607. { Sets the caret position and creates a selection between the anchor and the
  1608. caret position without scrolling the caret into view. }
  1609. begin
  1610. Call(SCI_SETCURRENTPOS, Value, 0);
  1611. end;
  1612. procedure TScintEdit.SetCaretVirtualSpace(const Value: Integer);
  1613. { Also sets the anchor's virtual space! }
  1614. var
  1615. Pos, LineEndPos, MainSel: Integer;
  1616. begin
  1617. { Weird things happen if a non-zero virtual space is set when the caret
  1618. isn't at the end of a line, so don't allow it }
  1619. Pos := GetCaretPosition;
  1620. LineEndPos := GetLineEndPosition(GetLineFromPosition(Pos));
  1621. if (Pos = LineEndPos) or (Value = 0) then begin
  1622. MainSel := GetMainSelection;
  1623. SetSelectionAnchorVirtualSpace(MainSel, Value);
  1624. SetSelectionCaretVirtualSpace(MainSel, Value);
  1625. ChooseCaretX;
  1626. end;
  1627. end;
  1628. procedure TScintEdit.SetChangeHistory(const Value: TScintChangeHistory);
  1629. begin
  1630. if FChangeHistory <> Value then begin
  1631. FChangeHistory := Value;
  1632. ApplyOptions;
  1633. end;
  1634. end;
  1635. procedure TScintEdit.SetCodePage(const Value: Integer);
  1636. begin
  1637. if FCodePage <> Value then begin
  1638. FCodePage := Value;
  1639. UpdateCodePage;
  1640. end;
  1641. end;
  1642. procedure TScintEdit.SetCursorID(const CursorID: Integer);
  1643. begin
  1644. Call(SCI_SETCURSOR, CursorID, 0);
  1645. end;
  1646. procedure TScintEdit.SetDefaultWordChars;
  1647. begin
  1648. SetWordChars(GetDefaultWordChars);
  1649. end;
  1650. procedure TScintEdit.SetEmptySelection;
  1651. { Make the main selection empty and removes additional selections without
  1652. scrolling the caret into view }
  1653. begin
  1654. Call(SCI_SETEMPTYSELECTION, GetCaretPosition, 0);
  1655. end;
  1656. procedure TScintEdit.SetEmptySelections;
  1657. { Makes all selections empty without scrolling the caret into view }
  1658. begin
  1659. for var Selection := 0 to SelectionCount-1 do begin
  1660. var Pos := SelectionCaretPosition[Selection];
  1661. SelectionAnchorPosition[Selection] := Pos;
  1662. end;
  1663. end;
  1664. procedure TScintEdit.SetFillSelectionToEdge(const Value: Boolean);
  1665. begin
  1666. if FFillSelectionToEdge <> Value then begin
  1667. FFillSelectionToEdge := Value;
  1668. ApplyOptions;
  1669. end;
  1670. end;
  1671. procedure TScintEdit.SetFoldFlags(const Value: TScintFoldFlags);
  1672. begin
  1673. var Flags := 0;
  1674. if sffLineBeforeExpanded in Value then
  1675. Flags := Flags or SC_FOLDFLAG_LINEBEFORE_EXPANDED;
  1676. if sffLineBeforeContracted in Value then
  1677. Flags := Flags or SC_FOLDFLAG_LINEBEFORE_CONTRACTED;
  1678. if sffLineAfterExpanded in Value then
  1679. Flags := Flags or SC_FOLDFLAG_LINEAFTER_EXPANDED;
  1680. if sffLineAfterContracted in Value then
  1681. Flags := Flags or SC_FOLDFLAG_LINEAFTER_CONTRACTED;
  1682. if sffLevelNumbers in Value then
  1683. Flags := Flags or SC_FOLDFLAG_LEVELNUMBERS
  1684. else if sffLineState in Value then
  1685. Flags := Flags or SC_FOLDFLAG_LINESTATE;
  1686. Call(SCI_SETFOLDFLAGS, Flags, 0);
  1687. var FoldLevelNumbersOrLineState := Value * [sffLevelNumbers, sffLineState] <> [];
  1688. if FoldLevelNumbersOrLineState <> FFoldLevelNumbersOrLineState then begin
  1689. FFoldLevelNumbersOrLineState := FoldLevelNumbersOrLineState;
  1690. UpdateLineNumbersWidth;
  1691. end;
  1692. end;
  1693. procedure TScintEdit.SetIndicators(const StartPos, EndPos: Integer;
  1694. const IndicatorNumber: TScintIndicatorNumber; const Value: Boolean);
  1695. begin
  1696. CheckPosRange(StartPos, EndPos);
  1697. Call(SCI_SETINDICATORCURRENT, IndicatorNumber, 0);
  1698. if Value then begin
  1699. Call(SCI_SETINDICATORVALUE, IndicatorNumber, 1);
  1700. Call(SCI_INDICATORFILLRANGE, StartPos, EndPos - StartPos);
  1701. end else
  1702. Call(SCI_INDICATORCLEARRANGE, StartPos, EndPos - StartPos);
  1703. end;
  1704. procedure TScintEdit.SetLineIndentation(const Line, Indentation: Integer);
  1705. begin
  1706. FLines.CheckIndexRange(Line);
  1707. Call(SCI_SETLINEINDENTATION, Line, Indentation);
  1708. end;
  1709. procedure TScintEdit.SetIndentationGuides(const Value: TScintIndentationGuides);
  1710. begin
  1711. if FIndentationGuides <> Value then begin
  1712. FIndentationGuides := Value;
  1713. ApplyOptions;
  1714. end;
  1715. end;
  1716. procedure TScintEdit.SetLineNumbers(const Value: Boolean);
  1717. begin
  1718. if FLineNumbers <> Value then begin
  1719. FLineNumbers := Value;
  1720. UpdateLineNumbersWidth;
  1721. end;
  1722. end;
  1723. procedure TScintEdit.SetMainSelection(const Value: Integer);
  1724. begin
  1725. Call(SCI_SETMAINSELECTION, Value, 0);
  1726. end;
  1727. procedure TScintEdit.SetMainSelText(const Value: String);
  1728. begin
  1729. SetRawMainSelText(ConvertStringToRawString(Value));
  1730. end;
  1731. procedure TScintEdit.SetRawMainSelText(const Value: TScintRawString);
  1732. begin
  1733. ReplaceRawMainSelText(Value, srmMinimal);
  1734. end;
  1735. procedure TScintEdit.SetRawSelText(const Value: TScintRawString);
  1736. { Replaces the main selection's text and *clears* additional selections }
  1737. begin
  1738. Call(SCI_REPLACESEL, 0, Value);
  1739. end;
  1740. procedure TScintEdit.SetRawText(const Value: TScintRawString);
  1741. begin
  1742. { Workaround: Without this call, if the caret is on line 0 and out in
  1743. virtual space, it'll remain in virtual space after the replacement }
  1744. Call(SCI_CLEARSELECTIONS, 0, 0);
  1745. { Using ReplaceRawTextRange instead of SCI_SETTEXT for embedded null support }
  1746. ReplaceRawTextRange(0, GetRawTextLength, Value);
  1747. ChooseCaretX;
  1748. end;
  1749. procedure TScintEdit.SetReadOnly(const Value: Boolean);
  1750. begin
  1751. Call(SCI_SETREADONLY, Ord(Value), 0);
  1752. end;
  1753. procedure TScintEdit.SetSavePoint;
  1754. begin
  1755. if FForceModified then begin
  1756. FForceModified := False;
  1757. if Assigned(FOnModifiedChange) then
  1758. FOnModifiedChange(Self);
  1759. end;
  1760. Call(SCI_SETSAVEPOINT, 0, 0);
  1761. end;
  1762. procedure TScintEdit.SetSelection(const Value: TScintRange);
  1763. { Sets the main selection and removes additional selections. Very similar
  1764. to SetSingleSelection, not sure why both messages exist and are slightly
  1765. different }
  1766. begin
  1767. Call(SCI_SETSEL, Value.StartPos, Value.EndPos);
  1768. end;
  1769. procedure TScintEdit.SetSelectionAnchorPosition(Selection: Integer;
  1770. const Value: Integer);
  1771. { Also sets anchors's virtual space to 0 }
  1772. begin
  1773. Call(SCI_SETSELECTIONNANCHOR, Selection, Value);
  1774. end;
  1775. procedure TScintEdit.SetSelectionAnchorVirtualSpace(Selection: Integer;
  1776. const Value: Integer);
  1777. begin
  1778. Call(SCI_SETSELECTIONNANCHORVIRTUALSPACE, Selection, Value);
  1779. end;
  1780. procedure TScintEdit.SetSelectionCaretPosition(Selection: Integer;
  1781. const Value: Integer);
  1782. { Also sets caret's virtual space to 0 }
  1783. begin
  1784. Call(SCI_SETSELECTIONNCARET, Selection, Value);
  1785. end;
  1786. procedure TScintEdit.SetSelectionCaretVirtualSpace(Selection: Integer;
  1787. const Value: Integer);
  1788. begin
  1789. Call(SCI_SETSELECTIONNCARETVIRTUALSPACE, Selection, Value);
  1790. end;
  1791. procedure TScintEdit.SetSelectionMode(const Value: TScintSelectionMode);
  1792. begin
  1793. var Mode: Integer;
  1794. if Value = ssmStream then
  1795. Mode := SC_SEL_STREAM
  1796. else if Value = ssmRectangular then
  1797. Mode := SC_SEL_RECTANGLE
  1798. else if Value = ssmLines then
  1799. Mode := SC_SEL_LINES
  1800. else
  1801. Mode := SC_SEL_THIN;
  1802. { Note this uses *CHANGE* and not *SET* }
  1803. Call(SCI_CHANGESELECTIONMODE, Mode, 0);
  1804. end;
  1805. procedure TScintEdit.SetSelText(const Value: String);
  1806. begin
  1807. SetRawSelText(ConvertStringToRawString(Value));
  1808. end;
  1809. procedure TScintEdit.SetSingleSelection(const CaretPos, AnchorPos: Integer);
  1810. { Sets the main selection and removes additional selections without scrolling
  1811. the caret into view }
  1812. begin
  1813. Call(SCI_SETSELECTION, CaretPos, AnchorPos);
  1814. end;
  1815. procedure TScintEdit.SetStyler(const Value: TScintCustomStyler);
  1816. begin
  1817. if FStyler <> Value then begin
  1818. if Assigned(Value) then
  1819. Value.FreeNotification(Self);
  1820. FStyler := Value;
  1821. if HandleAllocated then begin
  1822. Call(SCI_CLEARDOCUMENTSTYLE, 0, 0);
  1823. Call(SCI_STARTSTYLING, 0, 0);
  1824. UpdateStyleAttributes;
  1825. end;
  1826. end;
  1827. end;
  1828. procedure TScintEdit.SetTabWidth(const Value: Integer);
  1829. begin
  1830. if (FTabWidth <> Value) and (Value > 0) and (Value < 100) then begin
  1831. FTabWidth := Value;
  1832. ApplyOptions;
  1833. end;
  1834. end;
  1835. procedure TScintEdit.SetTarget(const StartPos, EndPos: Integer);
  1836. begin
  1837. Call(SCI_SETTARGETSTART, StartPos, 0);
  1838. Call(SCI_SETTARGETEND, EndPos, 0);
  1839. end;
  1840. procedure TScintEdit.SetTopLine(const Value: Integer);
  1841. begin
  1842. Call(SCI_SETFIRSTVISIBLELINE, Value, 0);
  1843. end;
  1844. procedure TScintEdit.SetUseStyleAttributes(const Value: Boolean);
  1845. begin
  1846. if FUseStyleAttributes <> Value then begin
  1847. FUseStyleAttributes := Value;
  1848. UpdateStyleAttributes;
  1849. end;
  1850. end;
  1851. procedure TScintEdit.SetUseTabCharacter(const Value: Boolean);
  1852. begin
  1853. if FUseTabCharacter <> Value then begin
  1854. FUseTabCharacter := Value;
  1855. ApplyOptions;
  1856. end;
  1857. end;
  1858. procedure TScintEdit.SetVirtualSpaceOptions(const Value: TScintVirtualSpaceOptions);
  1859. begin
  1860. if FVirtualSpaceOptions <> Value then begin
  1861. FVirtualSpaceOptions := Value;
  1862. ApplyOptions;
  1863. end;
  1864. end;
  1865. procedure TScintEdit.SetWordChars(const S: AnsiString);
  1866. begin
  1867. FWordChars := S;
  1868. FWordCharsAsSet := [];
  1869. for var C in S do
  1870. Include(FWordCharsAsSet, C);
  1871. Call(SCI_SETWORDCHARS, 0, S);
  1872. end;
  1873. procedure TScintEdit.SetWordWrap(const Value: Boolean);
  1874. begin
  1875. if FWordWrap <> Value then begin
  1876. FWordWrap := Value;
  1877. ApplyOptions;
  1878. end;
  1879. end;
  1880. procedure TScintEdit.SetZoom(const Value: Integer);
  1881. begin
  1882. Call(SCI_SETZOOM, Value, 0);
  1883. end;
  1884. procedure TScintEdit.ShowAutoComplete(const CharsEntered: Integer;
  1885. const WordList: AnsiString);
  1886. begin
  1887. Call(SCI_AUTOCSHOW, CharsEntered, WordList);
  1888. end;
  1889. procedure TScintEdit.ShowCallTip(const Pos: Integer;
  1890. const Definition: AnsiString);
  1891. begin
  1892. Call(SCI_CALLTIPSHOW, Pos, Definition);
  1893. end;
  1894. procedure TScintEdit.StyleNeeded(const EndPos: Integer);
  1895. function CalcCaretIndex(const FirstLine, LastLine: Integer): Integer;
  1896. var
  1897. CaretPos, StartPos, EndPos: Integer;
  1898. begin
  1899. Result := 0;
  1900. if FReportCaretPositionToStyler then begin
  1901. CaretPos := GetCaretPosition;
  1902. StartPos := GetPositionFromLine(FirstLine);
  1903. EndPos := GetLineEndPosition(LastLine);
  1904. if (CaretPos >= StartPos) and (CaretPos <= EndPos) then
  1905. Result := CaretPos - StartPos + 1;
  1906. end;
  1907. end;
  1908. procedure MaskDoubleByteCharacters(var S: TScintRawString);
  1909. var
  1910. Len, I: Integer;
  1911. begin
  1912. { This replaces all lead and trail bytes in S with #$80 and #$81 to
  1913. ensure that stylers do not mistake trail bytes for single-byte ASCII
  1914. characters (e.g. #131'A' is a valid combination on CP 932). }
  1915. if not FEffectiveCodePageDBCS then
  1916. Exit;
  1917. Len := Length(S);
  1918. I := 1;
  1919. while I <= Len do begin
  1920. if S[I] in FLeadBytes then begin
  1921. S[I] := #$80;
  1922. if I < Len then begin
  1923. Inc(I);
  1924. S[I] := #$81;
  1925. end;
  1926. end;
  1927. Inc(I);
  1928. end;
  1929. end;
  1930. function LineSpans(const Line: Integer): Boolean;
  1931. var
  1932. S: TScintRawString;
  1933. begin
  1934. S := FLines.RawLines[Line];
  1935. MaskDoubleByteCharacters(S);
  1936. Result := FStyler.LineTextSpans(S);
  1937. end;
  1938. function StyleLine(const FirstLine: Integer; const StartStylingPos: Integer): Integer;
  1939. begin
  1940. { Find final line in series of spanned lines }
  1941. var LastLine := FirstLine;
  1942. while (LastLine < Lines.Count - 1) and LineSpans(LastLine) do
  1943. Inc(LastLine);
  1944. { We don't pass line endings to the styler, because when the style of a
  1945. line ending changes, Scintilla assumes it must be a 'hanging' style and
  1946. immediately repaints all subsequent lines. (To see this in the IS IDE,
  1947. insert and remove a ';' character before a [Setup] directive, i.e.
  1948. toggle comment styling.) }
  1949. FStyler.FCaretIndex := CalcCaretIndex(FirstLine, LastLine);
  1950. FStyler.FCurIndex := 1;
  1951. FStyler.FStyleStartIndex := 1;
  1952. FStyler.FLineState := 0;
  1953. if FirstLine > 0 then
  1954. FStyler.FLineState := FLines.GetState(FirstLine-1);
  1955. FStyler.FText := GetRawTextRange(GetPositionFromLine(FirstLine),
  1956. GetLineEndPosition(LastLine));
  1957. MaskDoubleByteCharacters(FStyler.FText);
  1958. FStyler.FTextLen := Length(FStyler.FText);
  1959. FStyler.FStyleStr := StringOfChar(AnsiChar(0), FStyler.FTextLen +
  1960. FLines.GetLineEndingLength(LastLine));
  1961. var PreviousLineState := FStyler.LineState;
  1962. FStyler.StyleNeeded;
  1963. var N := Length(FStyler.FStyleStr);
  1964. if N > 0 then begin
  1965. var HadStyleByteIndicators := False;
  1966. { Apply style byte indicators. Add first as INDICATOR_CONTAINER and so on. }
  1967. for var Indicator := 0 to High(TScintStyleByteIndicatorNumber) do begin
  1968. var PrevI := 1;
  1969. var PrevValue := Indicator in TScintStyleByteIndicatorNumbers(Byte(Ord(FStyler.FStyleStr[1]) shr StyleNumberBits));
  1970. for var CurI := 2 to N do begin
  1971. var CurValue := Indicator in TScintStyleByteIndicatorNumbers(Byte(Ord(FStyler.FStyleStr[CurI]) shr StyleNumberBits));
  1972. if CurValue <> PrevValue then begin
  1973. SetIndicators(StartStylingPos+PrevI-1, StartStylingPos+CurI-1, Ord(Indicator)+INDICATOR_CONTAINER, PrevValue);
  1974. HadStyleByteIndicators := HadStyleByteIndicators or PrevValue;
  1975. PrevI := CurI;
  1976. PrevValue := CurValue;
  1977. end;
  1978. end;
  1979. SetIndicators(StartStylingPos+PrevI-1, StartStylingPos+N, Ord(Indicator)+INDICATOR_CONTAINER, PrevValue);
  1980. HadStyleByteIndicators := HadStyleByteIndicators or PrevValue;
  1981. end;
  1982. { Apply styles after removing any style byte indicators }
  1983. if HadStyleByteIndicators then
  1984. for var I := 1 to N do
  1985. FStyler.FStyleStr[I] := AnsiChar(Ord(FStyler.FStyleStr[I]) and StyleNumberMask);
  1986. Call(SCI_SETSTYLINGEX, Length(FStyler.FStyleStr), FStyler.FStyleStr);
  1987. FStyler.FStyleStr := '';
  1988. FStyler.FText := '';
  1989. end;
  1990. { Get fold level }
  1991. var LineState := FStyler.LineState;
  1992. var FoldLevel: Integer;
  1993. var FoldHeader, EnableFoldHeaderOnPrevious: Boolean;
  1994. FStyler.GetFoldLevel(LineState, PreviousLineState, FoldLevel, FoldHeader, EnableFoldHeaderOnPrevious);
  1995. Inc(FoldLevel, SC_FOLDLEVELBASE);
  1996. if FoldHeader then
  1997. FoldLevel := FoldLevel or SC_FOLDLEVELHEADERFLAG;
  1998. { Apply line state and fold level }
  1999. for var I := FirstLine to LastLine do begin
  2000. var OldState := FLines.GetState(I);
  2001. if FStyler.FLineState <> OldState then
  2002. Call(SCI_SETLINESTATE, I, FStyler.FLineState);
  2003. var OldLevel := Call(SCI_GETFOLDLEVEL, I, 0);
  2004. var NewLevel := FoldLevel;
  2005. { Setting SC_FOLDLEVELWHITEFLAG on empty lines causes a problem: when
  2006. Scintilla auto expands a contracted section (for example after removing ']'
  2007. from a section header) all the empty lines stay invisible, even any which
  2008. are in the middle of the section. See https://sourceforge.net/p/scintilla/bugs/2442/ }
  2009. //if FLines.GetRawLineLength(I) = 0 then
  2010. // NewLevel := NewLevel or SC_FOLDLEVELWHITEFLAG;
  2011. if NewLevel <> OldLevel then
  2012. Call(SCI_SETFOLDLEVEL, I, NewLevel);
  2013. end;
  2014. { Retroactively set header on previous line if requested to do so. Must be
  2015. *after* the loop above. Not sure why. Problem reproduction: move code above
  2016. the loop, run it, open Debug.iss, change [Setup] to [Set up] and notice
  2017. styling of the [Languages] section below it is now broken. If you turn on
  2018. sffLevelNumbers you will also see that the first entry in that section got
  2019. a header flag. }
  2020. if (FirstLine > 0) and EnableFoldHeaderOnPrevious then begin
  2021. var PreviousLine := FirstLine-1;
  2022. var OldLevel := Call(SCI_GETFOLDLEVEL, PreviousLine, 0);
  2023. var NewLevel := OldLevel or SC_FOLDLEVELHEADERFLAG;
  2024. if NewLevel <> OldLevel then
  2025. Call(SCI_SETFOLDLEVEL, PreviousLine, NewLevel);
  2026. end;
  2027. Result := LastLine;
  2028. end;
  2029. procedure DefaultStyleLine(const Line: Integer);
  2030. var
  2031. StyleStr: AnsiString;
  2032. begin
  2033. { Note: Using SCI_SETSTYLINGEX because it only redraws the part of the
  2034. range that changed, whereas SCI_SETSTYLING redraws the entire range. }
  2035. StyleStr := StringOfChar(AnsiChar(0), FLines.GetRawLineLengthWithEnding(Line));
  2036. Call(SCI_SETSTYLINGEX, Length(StyleStr), StyleStr);
  2037. end;
  2038. var
  2039. StartPos, StartLine, EndLine, Line: Integer;
  2040. begin
  2041. StartPos := Call(SCI_GETENDSTYLED, 0, 0);
  2042. StartLine := GetLineFromPosition(StartPos);
  2043. { EndPos (always?) points to the position *after* the last character of the
  2044. last line needing styling (usually an LF), so subtract 1 to avoid
  2045. restyling one extra line unnecessarily.
  2046. But don't do this if we're being asked to style all the way to the end.
  2047. When the document's last line is empty, 'EndPos - 1' will point to the
  2048. line preceding the last line, so StyleLine() will never be called on the
  2049. last line, and it will never be assigned a LINESTATE. This causes IS's
  2050. autocompletion to think the last line's section is scNone. }
  2051. if EndPos < GetRawTextLength then
  2052. EndLine := GetLineFromPosition(EndPos - 1)
  2053. else
  2054. EndLine := GetLineFromPosition(EndPos);
  2055. //outputdebugstring('-----');
  2056. //outputdebugstring(pchar(format('StyleNeeded poses: %d, %d', [StartPos, EndPos])));
  2057. //outputdebugstring(pchar(format('StyleNeeded lines: %d, %d', [StartLine, EndLine])));
  2058. { If StartLine is within a series of spanned lines, back up }
  2059. if Assigned(FStyler) then
  2060. while (StartLine > 0) and (LineSpans(StartLine - 1)) do
  2061. Dec(StartLine);
  2062. Line := StartLine;
  2063. while Line <= EndLine do begin
  2064. var StartStylingPos := GetPositionFromLine(Line);
  2065. Call(SCI_STARTSTYLING, StartStylingPos, 0);
  2066. if Assigned(FStyler) then
  2067. Line := StyleLine(Line, StartStylingPos)
  2068. else
  2069. DefaultStyleLine(Line);
  2070. Inc(Line);
  2071. end;
  2072. end;
  2073. procedure TScintEdit.SysColorChange(const Message: TMessage);
  2074. begin
  2075. ForwardMessage(Message);
  2076. end;
  2077. function TScintEdit.TestRawRegularExpression(const S: TScintRawString): Boolean;
  2078. { Example invalid regular expression: ( }
  2079. begin
  2080. Call(SCI_SETTARGETRANGE, 0, 0);
  2081. Call(SCI_SETSEARCHFLAGS, GetSearchFlags([sfoRegEx]), 0);
  2082. var WarnStatus: Integer;
  2083. var Res := Call(SCI_SEARCHINTARGET, Length(S), S, WarnStatus);
  2084. Result := not ((Res = -1) and (WarnStatus = SC_STATUS_WARN_REGEX));
  2085. end;
  2086. function TScintEdit.TestRegularExpression(const S: String): Boolean;
  2087. begin
  2088. Result := TestRawRegularExpression(ConvertStringToRawString(S));
  2089. end;
  2090. procedure TScintEdit.Undo;
  2091. begin
  2092. Call(SCI_UNDO, 0, 0);
  2093. end;
  2094. procedure TScintEdit.UpdateCodePage;
  2095. procedure InitLeadBytes;
  2096. var
  2097. Info: TCPInfo;
  2098. I: Integer;
  2099. J: Byte;
  2100. begin
  2101. FLeadBytes := [];
  2102. if FEffectiveCodePageDBCS and GetCPInfo(FEffectiveCodePage, Info) then begin
  2103. I := 0;
  2104. while (I < MAX_LEADBYTES) and ((Info.LeadByte[I] or Info.LeadByte[I+1]) <> 0) do begin
  2105. for J := Info.LeadByte[I] to Info.LeadByte[I+1] do
  2106. Include(FLeadBytes, AnsiChar(J));
  2107. Inc(I, 2);
  2108. end;
  2109. end;
  2110. end;
  2111. var
  2112. CP: Integer;
  2113. begin
  2114. if HandleAllocated then begin
  2115. { To Scintilla, code page 0 does not mean the current ANSI code page, but
  2116. an unspecified single byte code page. So that DBCS support is properly
  2117. enabled when running on a DBCS ANSI code page, replace 0 with GetACP. }
  2118. CP := FCodePage;
  2119. if CP = 0 then
  2120. CP := GetACP;
  2121. Call(SCI_SETCODEPAGE, CP, 0);
  2122. { Scintilla ignores attempts to set a code page it has no special support
  2123. for. But the editor could currently be set for UTF-8 or DBCS, so get it
  2124. out of that mode by setting the code page to 0 (a value it does
  2125. recognize). }
  2126. if Call(SCI_GETCODEPAGE, 0, 0) <> CP then
  2127. Call(SCI_SETCODEPAGE, 0, 0);
  2128. FEffectiveCodePage := Call(SCI_GETCODEPAGE, 0, 0);
  2129. FEffectiveCodePageDBCS := (FEffectiveCodePage <> 0) and
  2130. (FEffectiveCodePage <> SC_CP_UTF8);
  2131. InitLeadBytes;
  2132. end;
  2133. end;
  2134. procedure TScintEdit.UpdateLineNumbersWidth;
  2135. var
  2136. LineCount, PixelWidth: Integer;
  2137. Nines: String;
  2138. begin
  2139. if FLineNumbers or FFoldLevelNumbersOrLineState then begin
  2140. { Note: Based on SciTE's SciTEBase::SetLineNumberWidth. }
  2141. if FFoldLevelNumbersOrLineState then
  2142. Nines := StringOfChar('9', 12)
  2143. else begin
  2144. LineCount := Call(SCI_GETLINECOUNT, 0, 0);
  2145. Nines := '9';
  2146. while LineCount >= 10 do begin
  2147. LineCount := LineCount div 10;
  2148. Nines := Nines + '9';
  2149. end;
  2150. end;
  2151. PixelWidth := 4 + Call(SCI_TEXTWIDTH, STYLE_LINENUMBER, AnsiString(Nines));
  2152. end else
  2153. PixelWidth := 0;
  2154. Call(SCI_SETMARGINWIDTHN, 0, PixelWidth);
  2155. end;
  2156. procedure TScintEdit.UpdateStyleAttributes;
  2157. var
  2158. DefaultAttr: TScintStyleAttributes;
  2159. procedure SetStyleAttr(const StyleNumber: Integer;
  2160. const Attr: TScintStyleAttributes; const Force: Boolean);
  2161. begin
  2162. if Force or (Attr.FontName <> DefaultAttr.FontName) then
  2163. Call(SCI_STYLESETFONT, StyleNumber, AnsiString(Attr.FontName));
  2164. if Force or (Attr.FontSize <> DefaultAttr.FontSize) then
  2165. { Note: Scintilla doesn't support negative point sizes like the VCL }
  2166. Call(SCI_STYLESETSIZE, StyleNumber, Abs(Attr.FontSize));
  2167. if Force or (Attr.FontCharset <> DefaultAttr.FontCharset) then
  2168. Call(SCI_STYLESETCHARACTERSET, StyleNumber, Attr.FontCharset);
  2169. if Force or (Attr.FontStyle <> DefaultAttr.FontStyle) then begin
  2170. Call(SCI_STYLESETBOLD, StyleNumber, Ord(fsBold in Attr.FontStyle));
  2171. Call(SCI_STYLESETITALIC, StyleNumber, Ord(fsItalic in Attr.FontStyle));
  2172. Call(SCI_STYLESETUNDERLINE, StyleNumber, Ord(fsUnderline in Attr.FontStyle));
  2173. end;
  2174. if Force or (Attr.ForeColor <> DefaultAttr.ForeColor) then
  2175. Call(SCI_STYLESETFORE, StyleNumber, ColorToRGB(Attr.ForeColor));
  2176. if Force or (Attr.BackColor <> DefaultAttr.BackColor) then
  2177. Call(SCI_STYLESETBACK, StyleNumber, ColorToRGB(Attr.BackColor));
  2178. end;
  2179. procedure SetStyleAttrFromStyler(const StyleNumber: Integer);
  2180. var
  2181. Attr: TScintStyleAttributes;
  2182. begin
  2183. Attr := DefaultAttr;
  2184. FStyler.GetStyleAttributes(StyleNumber, Attr);
  2185. SetStyleAttr(StyleNumber, Attr, False);
  2186. end;
  2187. var
  2188. I: Integer;
  2189. begin
  2190. if not HandleAllocated then
  2191. Exit;
  2192. Call(SCI_SETCARETFORE, ColorToRGB(Font.Color), 0);
  2193. DefaultAttr.FontName := Font.Name;
  2194. DefaultAttr.FontSize := Font.Size;
  2195. DefaultAttr.FontStyle := Font.Style;
  2196. DefaultAttr.FontCharset := Font.Charset;
  2197. DefaultAttr.ForeColor := Font.Color;
  2198. DefaultAttr.BackColor := Color;
  2199. Call(SCI_STYLERESETDEFAULT, 0, 0);
  2200. SetStyleAttr(STYLE_DEFAULT, DefaultAttr, True);
  2201. Call(SCI_STYLECLEARALL, 0, 0);
  2202. if Assigned(FStyler) then begin
  2203. if FUseStyleAttributes then begin
  2204. for I := 0 to StyleNumbers-1 do
  2205. SetStyleAttrFromStyler(I);
  2206. SetStyleAttrFromStyler(STYLE_BRACEBAD);
  2207. SetStyleAttrFromStyler(STYLE_BRACELIGHT);
  2208. SetStyleAttrFromStyler(STYLE_INDENTGUIDE);
  2209. end;
  2210. SetStyleAttrFromStyler(STYLE_LINENUMBER);
  2211. end;
  2212. if (AutoCompleteFontName <> '') or (AutoCompleteFontSize > 0) then begin
  2213. if AutoCompleteFontName <> '' then
  2214. DefaultAttr.FontName := AutoCompleteFontName;
  2215. if AutoCompleteFontSize > 0 then
  2216. DefaultAttr.FontSize := AutoCompleteFontSize;
  2217. DefaultAttr.FontStyle := [];
  2218. { Note: Scintilla doesn't actually use the colors set here }
  2219. DefaultAttr.ForeColor := clWindowText;
  2220. DefaultAttr.BackColor := clWindow;
  2221. if FAutoCompleteStyle = 0 then
  2222. FAutoCompleteStyle := Call(SCI_ALLOCATEEXTENDEDSTYLES, 1, 0);
  2223. SetStyleAttr(FAutoCompleteStyle, DefaultAttr, True);
  2224. Call(SCI_AUTOCSETSTYLE, FAutoCompleteStyle, 0);
  2225. end else
  2226. Call(SCI_AUTOCSETSTYLE, 0, 0);
  2227. end;
  2228. function TScintEdit.WordAtCaret: String;
  2229. begin
  2230. var Range := WordAtCaretRange;
  2231. Result := GetTextRange(Range.StartPos, Range.EndPos);
  2232. end;
  2233. function TScintEdit.WordAtCaretRange: TScintRange;
  2234. begin
  2235. var Pos := GetCaretPosition;
  2236. Result.StartPos := GetWordStartPosition(Pos, True);
  2237. Result.EndPos := GetWordEndPosition(Pos, True);
  2238. end;
  2239. procedure TScintEdit.ZoomIn;
  2240. begin
  2241. Call(SCI_ZOOMIN, 0, 0);
  2242. end;
  2243. procedure TScintEdit.ZoomOut;
  2244. begin
  2245. Call(SCI_ZOOMOUT, 0, 0);
  2246. end;
  2247. procedure TScintEdit.CMColorChanged(var Message: TMessage);
  2248. begin
  2249. inherited;
  2250. UpdateStyleAttributes;
  2251. end;
  2252. procedure TScintEdit.CMFontChanged(var Message: TMessage);
  2253. begin
  2254. inherited;
  2255. UpdateStyleAttributes;
  2256. end;
  2257. procedure TScintEdit.CMHintShow(var Message: TCMHintShow);
  2258. begin
  2259. inherited;
  2260. if Assigned(FOnHintShow) then
  2261. FOnHintShow(Self, Message.HintInfo^);
  2262. end;
  2263. procedure TScintEdit.CMSysColorChange(var Message: TMessage);
  2264. begin
  2265. inherited;
  2266. UpdateStyleAttributes;
  2267. end;
  2268. procedure TScintEdit.CNNotify(var Message: TWMNotify);
  2269. begin
  2270. Notify(PSCNotification(Message.NMHdr)^);
  2271. end;
  2272. procedure TScintEdit.WMDestroy(var Message: TWMDestroy);
  2273. begin
  2274. FDirectPtr := nil;
  2275. FDirectStatusFunction := nil;
  2276. inherited;
  2277. end;
  2278. procedure TScintEdit.DpiChanged(const Message: TMessage);
  2279. begin
  2280. ForwardMessage(Message);
  2281. end;
  2282. procedure TScintEdit.WMDropFiles(var Message: TWMDropFiles);
  2283. var
  2284. FileList: TStringList;
  2285. NumFiles, I: Integer;
  2286. Filename: array[0..MAX_PATH-1] of Char;
  2287. P: TPoint;
  2288. begin
  2289. FileList := nil;
  2290. try
  2291. if FAcceptDroppedFiles and Assigned(FOnDropFiles) then begin
  2292. FileList := TStringList.Create;
  2293. NumFiles := DragQueryFile(Message.Drop, UINT(-1), nil, 0);
  2294. for I := 0 to NumFiles-1 do
  2295. if DragQueryFile(Message.Drop, I, Filename,
  2296. SizeOf(Filename) div SizeOf(Filename[0])) <> 0 then
  2297. FileList.Add(Filename);
  2298. if FileList.Count > 0 then begin
  2299. if not DragQueryPoint(Message.Drop, P) then begin
  2300. P.X := -1;
  2301. P.Y := -1;
  2302. end;
  2303. FOnDropFiles(Self, P.X, P.Y, FileList);
  2304. end;
  2305. end;
  2306. finally
  2307. FileList.Free;
  2308. DragFinish(Message.Drop);
  2309. Message.Drop := 0;
  2310. end;
  2311. end;
  2312. procedure TScintEdit.WMEraseBkgnd(var Message: TMessage);
  2313. begin
  2314. { Bypass the VCL's WM_ERASEBKGND handler; it causes flicker when selecting +
  2315. scrolling downward using the mouse }
  2316. Message.Result := CallWindowProc(DefWndProc, Handle, Message.Msg,
  2317. Message.WParam, Message.LParam);
  2318. end;
  2319. procedure TScintEdit.WMGetDlgCode(var Message: TWMGetDlgCode);
  2320. begin
  2321. inherited;
  2322. Message.Result := Message.Result or (DLGC_WANTARROWS or DLGC_WANTTAB);
  2323. end;
  2324. procedure TScintEdit.WMMouseWheel(var Message: TMessage);
  2325. begin
  2326. { Bypass TControl's broken WM_MOUSEWHEEL handler: it translates WParamLo
  2327. from a combination of MK_* values to a TShiftState -- which is only
  2328. meaningful to the VCL -- but it doesn't restore the original value before
  2329. passing an unhandled WM_MOUSEWHEEL message up to DefWndProc. This causes
  2330. Scintilla to see Ctrl+wheel as Shift+wheel, breaking zoom. (Observed on
  2331. Delphi 2009 and still needed in Delphi 11.3.) }
  2332. Message.Result := CallWindowProc(DefWndProc, Handle, Message.Msg,
  2333. Message.WParam, Message.LParam);
  2334. end;
  2335. procedure TScintEdit.SettingChange(const Message: TMessage);
  2336. begin
  2337. ForwardMessage(Message);
  2338. end;
  2339. { TScintEditStrings }
  2340. procedure TScintEditStrings.CheckIndexRange(const Index: Integer);
  2341. begin
  2342. if (Index < 0) or (Index >= GetCount) then
  2343. Error(@SListIndexError, Index);
  2344. end;
  2345. procedure TScintEditStrings.CheckIndexRangePlusOne(const Index: Integer);
  2346. begin
  2347. if (Index < 0) or (Index > GetCount) then
  2348. Error(@SListIndexError, Index);
  2349. end;
  2350. procedure TScintEditStrings.Clear;
  2351. begin
  2352. FEdit.SetRawText('');
  2353. end;
  2354. procedure TScintEditStrings.Delete(Index: Integer);
  2355. var
  2356. StartPos, EndPos: Integer;
  2357. begin
  2358. CheckIndexRange(Index);
  2359. StartPos := FEdit.GetPositionFromLine(Index);
  2360. EndPos := FEdit.GetPositionFromLine(Index + 1);
  2361. FEdit.ReplaceRawTextRange(StartPos, EndPos, '');
  2362. end;
  2363. function TScintEditStrings.Get(Index: Integer): String;
  2364. begin
  2365. Result := FEdit.ConvertRawStringToString(GetRawLine(Index));
  2366. end;
  2367. function TScintEditStrings.GetCount: Integer;
  2368. begin
  2369. Result := FEdit.Call(SCI_GETLINECOUNT, 0, 0);
  2370. end;
  2371. function TScintEditStrings.GetLineEndingLength(const Index: Integer): Integer;
  2372. var
  2373. StartPos, EndPos: Integer;
  2374. begin
  2375. CheckIndexRange(Index);
  2376. StartPos := FEdit.GetLineEndPosition(Index);
  2377. EndPos := FEdit.GetPositionFromLine(Index + 1);
  2378. Result := EndPos - StartPos;
  2379. end;
  2380. function TScintEditStrings.GetRawLine(Index: Integer): TScintRawString;
  2381. var
  2382. StartPos, EndPos: Integer;
  2383. begin
  2384. CheckIndexRange(Index);
  2385. StartPos := FEdit.GetPositionFromLine(Index);
  2386. EndPos := FEdit.GetLineEndPosition(Index);
  2387. Result := FEdit.GetRawTextRange(StartPos, EndPos);
  2388. end;
  2389. function TScintEditStrings.GetRawLineLength(Index: Integer): Integer;
  2390. var
  2391. StartPos, EndPos: Integer;
  2392. begin
  2393. CheckIndexRange(Index);
  2394. StartPos := FEdit.GetPositionFromLine(Index);
  2395. EndPos := FEdit.GetLineEndPosition(Index);
  2396. Result := EndPos - StartPos;
  2397. end;
  2398. function TScintEditStrings.GetRawLineLengthWithEnding(Index: Integer): Integer;
  2399. var
  2400. StartPos, EndPos: Integer;
  2401. begin
  2402. CheckIndexRange(Index);
  2403. StartPos := FEdit.GetPositionFromLine(Index);
  2404. EndPos := FEdit.GetPositionFromLine(Index + 1);
  2405. Result := EndPos - StartPos;
  2406. end;
  2407. function TScintEditStrings.GetRawLineWithEnding(Index: Integer): TScintRawString;
  2408. var
  2409. StartPos, EndPos: Integer;
  2410. begin
  2411. CheckIndexRange(Index);
  2412. StartPos := FEdit.GetPositionFromLine(Index);
  2413. EndPos := FEdit.GetPositionFromLine(Index + 1);
  2414. Result := FEdit.GetRawTextRange(StartPos, EndPos);
  2415. end;
  2416. function TScintEditStrings.GetState(Index: Integer): TScintLineState;
  2417. begin
  2418. CheckIndexRange(Index);
  2419. Result := FEdit.Call(SCI_GETLINESTATE, Index, 0);
  2420. end;
  2421. function TScintEditStrings.GetTextStr: String;
  2422. begin
  2423. Result := FEdit.ConvertRawStringToString(FEdit.GetRawText);
  2424. end;
  2425. procedure TScintEditStrings.Insert(Index: Integer; const S: String);
  2426. begin
  2427. InsertRawLine(Index, FEdit.ConvertStringToRawString(S));
  2428. end;
  2429. procedure TScintEditStrings.InsertRawLine(Index: Integer; const S: TScintRawString);
  2430. var
  2431. Pos: Integer;
  2432. EndingStr, InsertStr: TScintRawString;
  2433. begin
  2434. CheckIndexRangePlusOne(Index);
  2435. EndingStr := FEdit.GetLineEndingString;
  2436. Pos := FEdit.GetPositionFromLine(Index);
  2437. if (Index = GetCount) and (Pos <> FEdit.GetPositionFromLine(Index - 1)) then
  2438. InsertStr := EndingStr + S + EndingStr
  2439. else
  2440. InsertStr := S + EndingStr;
  2441. { Using ReplaceRawTextRange instead of SCI_INSERTTEXT for embedded null support }
  2442. FEdit.ReplaceRawTextRange(Pos, Pos, InsertStr);
  2443. end;
  2444. procedure TScintEditStrings.Put(Index: Integer; const S: String);
  2445. begin
  2446. PutRawLine(Index, FEdit.ConvertStringToRawString(S));
  2447. end;
  2448. procedure TScintEditStrings.PutRawLine(Index: Integer; const S: TScintRawString);
  2449. var
  2450. StartPos, EndPos: Integer;
  2451. begin
  2452. CheckIndexRange(Index);
  2453. StartPos := FEdit.GetPositionFromLine(Index);
  2454. EndPos := FEdit.GetLineEndPosition(Index);
  2455. FEdit.ReplaceRawTextRange(StartPos, EndPos, S, srmMinimal);
  2456. end;
  2457. procedure TScintEditStrings.SetText(Text: PChar);
  2458. begin
  2459. FEdit.SetRawText(FEdit.ConvertPCharToRawString(Text, StrLen(Text)));
  2460. end;
  2461. procedure TScintEditStrings.SetTextStr(const Value: String);
  2462. begin
  2463. FEdit.SetRawText(FEdit.ConvertStringToRawString(Value));
  2464. end;
  2465. { TScintCustomStyler }
  2466. procedure TScintCustomStyler.ApplyStyleByteIndicators(const Indicators: TScintStyleByteIndicatorNumbers;
  2467. StartIndex, EndIndex: Integer);
  2468. begin
  2469. var IndByte := Byte(Indicators) shl StyleNumberBits;
  2470. if IndByte <> 0 then begin
  2471. if StartIndex < 1 then
  2472. StartIndex := 1;
  2473. if EndIndex > FTextLen then
  2474. EndIndex := FTextLen;
  2475. for var I := StartIndex to EndIndex do
  2476. FStyleStr[I] := AnsiChar(Ord(FStyleStr[I]) or IndByte);
  2477. end;
  2478. end;
  2479. procedure TScintCustomStyler.ApplyStyle(const Style: TScintStyleNumber;
  2480. StartIndex, EndIndex: Integer);
  2481. begin
  2482. if StartIndex < 1 then
  2483. StartIndex := 1;
  2484. if EndIndex > FTextLen then
  2485. EndIndex := FTextLen;
  2486. for var I := StartIndex to EndIndex do
  2487. if Ord(FStyleStr[I]) and StyleNumberMask = 0 then
  2488. FStyleStr[I] := AnsiChar(Style or (Ord(FStyleStr[I]) and not StyleNumberMask));
  2489. end;
  2490. procedure TScintCustomStyler.CommitStyle(const Style: TScintStyleNumber);
  2491. begin
  2492. ApplyStyle(Style, FStyleStartIndex, FCurIndex - 1);
  2493. FStyleStartIndex := FCurIndex;
  2494. end;
  2495. function TScintCustomStyler.ConsumeAllRemaining: Boolean;
  2496. begin
  2497. Result := FCurIndex <= FTextLen;
  2498. if Result then
  2499. FCurIndex := FTextLen + 1;
  2500. end;
  2501. function TScintCustomStyler.ConsumeChar(const C: AnsiChar): Boolean;
  2502. begin
  2503. Result := (FCurIndex <= FTextLen) and (FText[FCurIndex] = C);
  2504. if Result then
  2505. Inc(FCurIndex);
  2506. end;
  2507. function TScintCustomStyler.ConsumeCharIn(const Chars: TScintRawCharSet): Boolean;
  2508. begin
  2509. Result := (FCurIndex <= FTextLen) and (FText[FCurIndex] in Chars);
  2510. if Result then
  2511. Inc(FCurIndex);
  2512. end;
  2513. function TScintCustomStyler.ConsumeChars(const Chars: TScintRawCharSet): Boolean;
  2514. begin
  2515. Result := False;
  2516. while FCurIndex <= FTextLen do begin
  2517. if not(FText[FCurIndex] in Chars) then
  2518. Break;
  2519. Result := True;
  2520. Inc(FCurIndex);
  2521. end;
  2522. end;
  2523. function TScintCustomStyler.ConsumeCharsNot(const Chars: TScintRawCharSet): Boolean;
  2524. begin
  2525. Result := False;
  2526. while FCurIndex <= FTextLen do begin
  2527. if FText[FCurIndex] in Chars then
  2528. Break;
  2529. Result := True;
  2530. Inc(FCurIndex);
  2531. end;
  2532. end;
  2533. function TScintCustomStyler.ConsumeString(const Chars: TScintRawCharSet): TScintRawString;
  2534. var
  2535. StartIndex: Integer;
  2536. begin
  2537. StartIndex := FCurIndex;
  2538. ConsumeChars(Chars);
  2539. Result := Copy(FText, StartIndex, FCurIndex - StartIndex);
  2540. end;
  2541. function TScintCustomStyler.CurCharIn(const Chars: TScintRawCharSet): Boolean;
  2542. begin
  2543. Result := (FCurIndex <= FTextLen) and (FText[FCurIndex] in Chars);
  2544. end;
  2545. function TScintCustomStyler.CurCharIs(const C: AnsiChar): Boolean;
  2546. begin
  2547. Result := (FCurIndex <= FTextLen) and (FText[FCurIndex] = C);
  2548. end;
  2549. function TScintCustomStyler.GetCurChar: AnsiChar;
  2550. begin
  2551. Result := #0;
  2552. if FCurIndex <= FTextLen then
  2553. Result := FText[FCurIndex];
  2554. end;
  2555. function TScintCustomStyler.GetEndOfLine: Boolean;
  2556. begin
  2557. Result := FCurIndex > FTextLen;
  2558. end;
  2559. function TScintCustomStyler.LineTextSpans(const S: TScintRawString): Boolean;
  2560. begin
  2561. Result := False;
  2562. end;
  2563. function TScintCustomStyler.NextCharIs(const C: AnsiChar): Boolean;
  2564. begin
  2565. Result := (FCurIndex < FTextLen) and (FText[FCurIndex+1] = C);
  2566. end;
  2567. function TScintCustomStyler.PreviousCharIn(const Chars: TScintRawCharSet): Boolean;
  2568. begin
  2569. Result := (FCurIndex > 1) and (FCurIndex-1 <= FTextLen) and
  2570. (FText[FCurIndex-1] in Chars);
  2571. end;
  2572. procedure TScintCustomStyler.ReplaceText(StartIndex, EndIndex: Integer;
  2573. const C: AnsiChar);
  2574. var
  2575. P: PAnsiChar;
  2576. I: Integer;
  2577. begin
  2578. if StartIndex < 1 then
  2579. StartIndex := 1;
  2580. if EndIndex > FTextLen then
  2581. EndIndex := FTextLen;
  2582. P := @FText[1];
  2583. for I := StartIndex to EndIndex do
  2584. P[I-1] := C;
  2585. end;
  2586. procedure TScintCustomStyler.ResetCurIndexTo(Index: Integer);
  2587. begin
  2588. FCurIndex := Index;
  2589. FStyleStartIndex := Index;
  2590. end;
  2591. { TScintPixmap }
  2592. const
  2593. XPMTransparentChar = ' ';
  2594. XPMTerminatorChar = '"';
  2595. class constructor TScintPixmap.Create;
  2596. begin
  2597. { Chars 128-255 are supported below but don't work in Scintilla }
  2598. for var C := #1 to #127 do
  2599. if (C <> XPMTransparentChar) and (C <> XPMTerminatorChar) then
  2600. ColorCodes := ColorCodes + C;
  2601. end;
  2602. function TScintPixmap.GetPixmap: Pointer;
  2603. begin
  2604. Result := FPixmap;
  2605. end;
  2606. type
  2607. TRGBTripleArray = array[0..MaxInt div SizeOf(TRGBTriple) - 1] of TRGBTriple;
  2608. PRGBTripleArray = ^TRGBTripleArray;
  2609. procedure TScintPixmap.InitializeFromBitmap(const ABitmap: TBitmap;
  2610. const TransparentColor: TColorRef);
  2611. procedure SetNextPixmapLine(const Pixmap: TPixmap; var Index: Integer; const Line: String);
  2612. begin
  2613. if Index > High(Pixmap) then
  2614. TScintEdit.Error('SetNextPixmapLine: Index out of range');
  2615. { Convert Line to an AnsiString, but copy the exact ordinal values;
  2616. i.e. don't do any translation of 128-255 }
  2617. var AnsiLine: AnsiString;
  2618. SetLength(AnsiLine, Length(Line));
  2619. for var I := 1 to Length(AnsiLine) do
  2620. AnsiLine[I] := AnsiChar(Ord(Line[I]));
  2621. Pixmap[Index] := AnsiLine;
  2622. Inc(Index);
  2623. end;
  2624. begin
  2625. if ABitmap.PixelFormat <> pf24bit then
  2626. TScintEdit.Error('Invalid PixelFormat');
  2627. var Colors := TDictionary<Integer, TPair<Char, String>>.Create; { RGB -> Code & WebColor }
  2628. try
  2629. { Build colors list }
  2630. for var Y := 0 to ABitmap.Height-1 do begin
  2631. var Pixels: PRGBTripleArray := ABitmap.ScanLine[Y];
  2632. for var X := 0 to ABitmap.Width-1 do begin
  2633. var Color := RGB(Pixels[X].rgbtRed, Pixels[X].rgbtGreen, Pixels[X].rgbtBlue);
  2634. if (Color <> TransparentColor) and not Colors.ContainsKey(Color) then begin
  2635. var ColorCodeIndex := Colors.Count+1;
  2636. if ColorCodeIndex > Length(ColorCodes) then
  2637. TScintEdit.Error('Too many colors');
  2638. Colors.Add(Color, TPair<Char, String>.Create(ColorCodes[ColorCodeIndex], RGBToWebColorStr(Color)))
  2639. end;
  2640. end;
  2641. end;
  2642. { Build pixmap }
  2643. var Line: String;
  2644. SetLength(FPixmap, 0); { Not really needed but makes things clearer while debugging }
  2645. SetLength(FPixmap, 1 + Colors.Count + ABitmap.Height + 1);
  2646. Line := Format('%d %d %d 1', [ABitmap.Width, ABitmap.Height, Colors.Count]);
  2647. var Index := 0;
  2648. SetNextPixmapLine(FPixmap, Index, Line);
  2649. for var Color in Colors do begin
  2650. Line := Format('%s c %s', [Color.Value.Key, Color.Value.Value]);
  2651. SetNextPixmapLine(FPixmap, Index, Line);
  2652. end;
  2653. for var Y := 0 to ABitmap.Height-1 do begin
  2654. Line := '';
  2655. var Pixels: PRGBTripleArray := ABitmap.ScanLine[Y];
  2656. for var X := 0 to ABitmap.Width-1 do begin
  2657. var Color := RGB(Pixels[X].rgbtRed, Pixels[X].rgbtGreen, Pixels[X].rgbtBlue);
  2658. if Color = TransparentColor then
  2659. Line := Line + XPMTransparentChar
  2660. else
  2661. Line := Line + Colors[Color].Key;
  2662. end;
  2663. SetNextPixmapLine(FPixmap, Index, Line);
  2664. end;
  2665. { Add terminating nil pointer - Scintilla doesnt really need it but setting it anyway }
  2666. SetNextPixmapLine(FPixmap, Index, '');
  2667. finally
  2668. Colors.Free;
  2669. end;
  2670. end;
  2671. { TScintRange }
  2672. constructor TScintRange.Create(const AStartPos, AEndPos: Integer);
  2673. begin
  2674. StartPos := AStartPos;
  2675. EndPos := AEndPos;
  2676. end;
  2677. function TScintRange.Overlaps(const ARange: TScintRange): Boolean;
  2678. begin
  2679. Result := not ARange.Empty and (StartPos <= ARange.EndPos) and (EndPos >= ARange.StartPos);
  2680. end;
  2681. function TScintRange.Empty: Boolean;
  2682. begin
  2683. Result := StartPos = EndPos;
  2684. end;
  2685. function TScintRange.Within(const ARange: TScintRange): Boolean;
  2686. begin
  2687. Result := (StartPos >= ARange.StartPos) and (EndPos <= ARange.EndPos);
  2688. end;
  2689. { TScintRangeList }
  2690. function TScintRangeList.Overlaps(const ARange: TScintRange;
  2691. var AOverlappingRange: TScintRange): Boolean;
  2692. begin
  2693. for var Item in Self do begin
  2694. if Item.Overlaps(ARange) then begin
  2695. AOverlappingRange := Item;
  2696. Exit(True);
  2697. end;
  2698. end;
  2699. Result := False;
  2700. end;
  2701. { TScintCaretAndAnchor }
  2702. constructor TScintCaretAndAnchor.Create(const ACaretPos, AAnchorPos: Integer);
  2703. begin
  2704. CaretPos := ACaretPos;
  2705. AnchorPos := AAnchorPos;
  2706. end;
  2707. function TScintCaretAndAnchor.Range: TScintRange;
  2708. begin
  2709. if CaretPos <= AnchorPos then begin
  2710. Result.StartPos := CaretPos;
  2711. Result.EndPos := AnchorPos;
  2712. end else begin
  2713. Result.StartPos := AnchorPos;
  2714. Result.EndPos := CaretPos;
  2715. end;
  2716. end;
  2717. end.