weditor.pas 172 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333
  1. {
  2. This file is part of the Free Pascal Integrated Development Environment
  3. Copyright (c) 1998 by Berczi Gabor
  4. Code editor template objects
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {$I globdir.inc}
  12. unit WEditor;
  13. interface
  14. {tes}
  15. uses
  16. Dos,Objects,Drivers,Views,Menus,Commands,
  17. WUtils;
  18. const
  19. cmFileNameChanged = 51234;
  20. cmASCIIChar = 51235;
  21. cmClearLineHighlights = 51236;
  22. cmSaveCancelled = 51237;
  23. cmBreakLine = 51238;
  24. cmSelStart = 51239;
  25. cmSelEnd = 51240;
  26. cmLastCursorPos = 51241;
  27. cmIndentBlock = 51242;
  28. cmUnIndentBlock = 51243;
  29. cmSelectLine = 51244;
  30. cmWriteBlock = 51245;
  31. cmReadBlock = 51246;
  32. cmPrintBlock = 51247;
  33. cmResetDebuggerRow = 51248;
  34. cmAddChar = 51249;
  35. cmExpandCodeTemplate = 51250;
  36. cmUpperCase = 51251;
  37. cmLowerCase = 51252;
  38. cmWindowStart = 51253;
  39. cmWindowEnd = 51254;
  40. cmFindMatchingDelimiter= 51255;
  41. cmFindMatchingDelimiterBack=51256;
  42. cmActivateMenu = 51257;
  43. cmWordLowerCase = 51258;
  44. cmWordUpperCase = 51259;
  45. cmOpenAtCursor = 51260;
  46. cmBrowseAtCursor = 51261;
  47. cmInsertOptions = 51262;
  48. cmToggleCase = 51263;
  49. EditorTextBufSize = {$ifdef FPC}32768{$else} 4096{$endif};
  50. MaxLineLength = 255;
  51. MaxLineCount = {$ifdef FPC}2000000{$else}16380{$endif};
  52. CodeCompleteMinLen = 4; { minimum length of text to try to complete }
  53. efBackupFiles = $00000001;
  54. efInsertMode = $00000002;
  55. efAutoIndent = $00000004;
  56. efUseTabCharacters = $00000008;
  57. efBackSpaceUnindents = $00000010;
  58. efPersistentBlocks = $00000020;
  59. efSyntaxHighlight = $00000040;
  60. efBlockInsCursor = $00000080;
  61. efVerticalBlocks = $00000100;
  62. efHighlightColumn = $00000200;
  63. efHighlightRow = $00000400;
  64. efAutoBrackets = $00000800;
  65. efExpandAllTabs = $00001000;
  66. efKeepTrailingSpaces = $00002000;
  67. efCodeComplete = $00004000;
  68. efStoreContent = $80000000;
  69. attrAsm = 1;
  70. attrComment = 2;
  71. attrForceFull = 128;
  72. attrAll = attrAsm+attrComment;
  73. edOutOfMemory = 0;
  74. edReadError = 1;
  75. edWriteError = 2;
  76. edCreateError = 3;
  77. edSaveModify = 4;
  78. edSaveUntitled = 5;
  79. edSaveAs = 6;
  80. edFind = 7;
  81. edSearchFailed = 8;
  82. edReplace = 9;
  83. edReplacePrompt = 10;
  84. edTooManyLines = 11;
  85. edGotoLine = 12;
  86. edReplaceFile = 13;
  87. edWriteBlock = 14;
  88. edReadBlock = 15;
  89. edFileOnDiskChanged = 16;
  90. edChangedOnloading = 17;
  91. edSaveError = 18;
  92. ffmOptions = $0007; ffsOptions = 0;
  93. ffmDirection = $0008; ffsDirection = 3;
  94. ffmScope = $0010; ffsScope = 4;
  95. ffmOrigin = $0020; ffsOrigin = 5;
  96. ffDoReplace = $0040;
  97. ffReplaceAll = $0080;
  98. ffCaseSensitive = $0001;
  99. ffWholeWordsOnly = $0002;
  100. ffPromptOnReplace = $0004;
  101. ffForward = $0000;
  102. ffBackward = $0008;
  103. ffGlobal = $0000;
  104. ffSelectedText = $0010;
  105. ffFromCursor = $0000;
  106. ffEntireScope = $0020;
  107. coTextColor = 0;
  108. coWhiteSpaceColor = 1;
  109. coCommentColor = 2;
  110. coReservedWordColor = 3;
  111. coIdentifierColor = 4;
  112. coStringColor = 5;
  113. coNumberColor = 6;
  114. coAssemblerColor = 7;
  115. coSymbolColor = 8;
  116. coDirectiveColor = 9;
  117. coHexNumberColor = 10;
  118. coTabColor = 11;
  119. coBreakColor = 12;
  120. coFirstColor = 0;
  121. coLastColor = coBreakColor;
  122. lfBreakpoint = $0001;
  123. lfHighlightRow = $0002;
  124. lfDebuggerRow = $0004;
  125. eaMoveCursor = 1;
  126. eaInsertLine = 2;
  127. eaInsertText = 3;
  128. eaDeleteLine = 4;
  129. eaDeleteText = 5;
  130. eaSelectionChanged = 6;
  131. eaCut = 7;
  132. eaPaste = 8;
  133. eaPasteWin = 9;
  134. eaClear = 10;
  135. LastAction = eaClear;
  136. ActionString : array [0..LastAction] of string[8] =
  137. ('','Move','InsLine','InsText','DelLine','DelText',
  138. 'SelCh','Cut','Paste','PasteWin','Clear');
  139. CIndicator = #2#3#1;
  140. CEditor = #33#34#35#36#37#38#39#40#41#42#43#44#45#46#47#48#49;
  141. TAB = #9;
  142. FindStrSize = 79;
  143. type
  144. PCustomCodeEditor = ^TCustomCodeEditor;
  145. PEditorLineInfo = ^TEditorLineInfo;
  146. TEditorLineInfo = object(TObject)
  147. Editor: PCustomCodeEditor;
  148. Format : PString;
  149. BeginsWithAsm,
  150. EndsWithAsm : boolean;
  151. BeginsWithComment,
  152. EndsInSingleLineComment,
  153. EndsWithComment : boolean;
  154. BeginsWithDirective,
  155. EndsWithDirective : boolean;
  156. BeginCommentType,EndCommentType : byte;
  157. constructor Init(AEditor: PCustomCodeEditor);
  158. destructor Done; virtual;
  159. function GetFormat: string;
  160. procedure SetFormat(const AFormat: string);
  161. { Syntax information is now generated separately for each editor instance.
  162. This is not neccessary for a one-language IDE, but this unit contains
  163. a _generic_ editor object, which should be (and is) as flexible as
  164. possible.
  165. The overhead caused by generating the same syntax info for ex.
  166. twice isn't so much... - Gabor }
  167. end;
  168. PEditorLineInfoCollection = ^TEditorLineInfoCollection;
  169. TEditorLineInfoCollection = object(TCollection)
  170. function At(Index: sw_Integer): PEditorLineInfo;
  171. end;
  172. PCustomLine = ^TCustomLine;
  173. TCustomLine = object(TObject)
  174. constructor Init(const AText: string; AFlags: longint);
  175. {a}function GetText: string; virtual;
  176. {a}procedure SetText(const AText: string); virtual;
  177. {a}function GetEditorInfo(Editor: PCustomCodeEditor): PEditorLineInfo; virtual;
  178. {a}function GetFlags: longint; virtual;
  179. {a}procedure SetFlags(AFlags: longint); virtual;
  180. function IsFlagSet(AFlag: longint): boolean;
  181. procedure SetFlagState(AFlag: longint; ASet: boolean);
  182. destructor Done; virtual;
  183. public { internal use only! }
  184. {a}procedure AddEditorInfo(Index: sw_integer; AEditor: PCustomCodeEditor); virtual;
  185. {a}procedure RemoveEditorInfo(AEditor: PCustomCodeEditor); virtual;
  186. end;
  187. PLineCollection = ^TLineCollection;
  188. TLineCollection = object(TCollection)
  189. function At(Index: sw_Integer): PCustomLine;
  190. end;
  191. {$ifdef Undo}
  192. PEditorAction = ^TEditorAction;
  193. TEditorAction = object(TObject)
  194. StartPos : TPoint;
  195. EndPos : TPoint;
  196. Text : PString;
  197. ActionCount : longint;
  198. Action : byte;
  199. TimeStamp : longint; { this is needed to keep track of line number &
  200. position changes (for ex. for symbol browser)
  201. the line&pos references (eg. symbol info) should
  202. also contain such a timestamp. this will enable
  203. to determine which changes have been made since
  204. storage of the information and thus calculate
  205. the (probably) changed line & position information,
  206. so, we can still jump to the right position in the
  207. editor even when it is heavily modified - Gabor }
  208. constructor init(act:byte; StartP,EndP:TPoint;Txt:String);
  209. constructor init_group(act:byte);
  210. function is_grouped_action : boolean;
  211. destructor done; virtual;
  212. end;
  213. PEditorActionCollection = ^TEditorActionCollection;
  214. TEditorActionCollection = object(TCollection)
  215. CurrentGroupedAction : PEditorAction;
  216. function At(Idx : sw_integer) : PEditorAction;
  217. end;
  218. {$else}
  219. PEditorAction = ^TEditorAction;
  220. TEditorAction = packed record
  221. StartPos : TPoint;
  222. EndPos : TPoint;
  223. Text : PString;
  224. ActionCount : longint;
  225. Action : byte;
  226. TimeStamp : longint; { see above! }
  227. end;
  228. PEditorActionCollection = ^TEditorActionCollection;
  229. TEditorActionCollection = object(TCollection)
  230. function At(Idx : sw_integer) : PEditorAction;
  231. procedure FreeItem(Item: Pointer); virtual;
  232. end;
  233. {$endif Undo}
  234. TSpecSymbolClass =
  235. (ssCommentPrefix,ssCommentSingleLinePrefix,ssCommentSuffix,ssStringPrefix,ssStringSuffix,
  236. ssDirectivePrefix,ssDirectiveSuffix,ssAsmPrefix,ssAsmSuffix);
  237. TEditorBookMark = record
  238. Valid : boolean;
  239. Pos : TPoint;
  240. end;
  241. TCompleteState = (csInactive,csOffering,csDenied);
  242. PEditorBinding = ^TEditorBinding;
  243. PEditorBindingCollection = ^TEditorBindingCollection;
  244. TEditorBindingCollection = object(TCollection)
  245. function At(Index: sw_Integer): PEditorBinding;
  246. end;
  247. TEditorBinding = object(TObject)
  248. Editor : PCustomCodeEditor;
  249. constructor Init(AEditor: PCustomCodeEditor);
  250. destructor Done; virtual;
  251. end;
  252. PCustomCodeEditorCore = ^TCustomCodeEditorCore;
  253. TCustomCodeEditorCore = object(TObject)
  254. {$ifdef TP}public{$else}protected{$endif}
  255. Bindings : PEditorBindingCollection;
  256. LockFlag : sw_integer;
  257. ChangedLine : sw_integer;
  258. ContentsChangedCalled : boolean;
  259. LimitsChangedCalled : boolean;
  260. ModifiedChangedCalled : boolean;
  261. TabSizeChangedCalled : boolean;
  262. StoreUndoChangedCalled : boolean;
  263. {$ifdef TEST_PARTIAL_SYNTAX}
  264. LastSyntaxedLine : sw_integer;
  265. SyntaxComplete : boolean;
  266. {$endif TEST_PARTIAL_SYNTAX}
  267. public
  268. constructor Init;
  269. procedure BindEditor(AEditor: PCustomCodeEditor);
  270. procedure UnBindEditor(AEditor: PCustomCodeEditor);
  271. function IsEditorBound(AEditor: PCustomCodeEditor): boolean;
  272. function GetBindingCount: sw_integer;
  273. function GetBindingIndex(AEditor: PCustomCodeEditor): sw_integer;
  274. function SearchBinding(AEditor: PCustomCodeEditor): PEditorBinding;
  275. function CanDispose: boolean;
  276. destructor Done; virtual;
  277. public
  278. {a}function GetModified: boolean; virtual;
  279. function GetChangedLine: sw_integer;
  280. {a}procedure SetModified(AModified: boolean); virtual;
  281. {a}function GetStoreUndo: boolean; virtual;
  282. {a}procedure SetStoreUndo(AStore: boolean); virtual;
  283. {a}function GetSyntaxCompleted: boolean; virtual;
  284. {a}procedure SetSyntaxCompleted(SC: boolean); virtual;
  285. {a}function GetTabSize: integer; virtual;
  286. {a}procedure SetTabSize(ATabSize: integer); virtual;
  287. function IsClipboard: Boolean;
  288. public
  289. { Notifications }
  290. procedure BindingsChanged;
  291. procedure ContentsChanged;
  292. procedure LimitsChanged;
  293. procedure ModifiedChanged;
  294. procedure TabSizeChanged;
  295. procedure StoreUndoChanged;
  296. {a}procedure DoContentsChanged; virtual;
  297. {a}procedure DoLimitsChanged; virtual;
  298. {a}procedure DoModifiedChanged; virtual;
  299. {a}procedure DoTabSizeChanged; virtual;
  300. {a}procedure DoStoreUndoChanged; virtual;
  301. {a}procedure DoSyntaxStateChanged; virtual;
  302. function GetLastVisibleLine : sw_integer;
  303. public
  304. { Storage }
  305. function LoadFromStream(Editor: PCustomCodeEditor; Stream: PStream): boolean; virtual;
  306. function SaveToStream(Editor: PCustomCodeEditor; Stream: PStream): boolean; virtual;
  307. function SaveAreaToStream(Editor: PCustomCodeEditor; Stream: PStream; StartP,EndP: TPoint): boolean; virtual;
  308. {$ifdef TP}public{$else}protected{$endif}
  309. { Text & info storage abstraction }
  310. {a}procedure ISetLineFlagState(Binding: PEditorBinding; LineNo: sw_integer; Flag: longint; ASet: boolean); virtual;
  311. {a}procedure IGetDisplayTextFormat(Binding: PEditorBinding; LineNo: sw_integer;var DT,DF:string); virtual;
  312. {a}function IGetLineFormat(Binding: PEditorBinding; LineNo: sw_integer): string; virtual;
  313. {a}procedure ISetLineFormat(Binding: PEditorBinding; LineNo: sw_integer;const S: string); virtual;
  314. public
  315. { Text & info storage abstraction }
  316. function CharIdxToLinePos(Line,CharIdx: sw_integer): sw_integer;
  317. function LinePosToCharIdx(Line,X: sw_integer): sw_integer;
  318. {a}function GetLineCount: sw_integer; virtual;
  319. {a}function GetLine(LineNo: sw_integer): PCustomLine; virtual;
  320. {a}function GetLineText(LineNo: sw_integer): string; virtual;
  321. {a}procedure SetDisplayText(I: sw_integer;const S: string); virtual;
  322. {a}function GetDisplayText(I: sw_integer): string; virtual;
  323. {a}procedure SetLineText(I: sw_integer;const S: string); virtual;
  324. procedure GetDisplayTextFormat(Editor: PCustomCodeEditor; I: sw_integer;var DT,DF:string); virtual;
  325. function GetLineFormat(Editor: PCustomCodeEditor; I: sw_integer): string; virtual;
  326. procedure SetLineFormat(Editor: PCustomCodeEditor; I: sw_integer;const S: string); virtual;
  327. {a}procedure DeleteAllLines; virtual;
  328. {a}procedure DeleteLine(I: sw_integer); virtual;
  329. {a}procedure InsertLine(LineNo: sw_integer; const S: string); virtual;
  330. {a}procedure AddLine(const S: string); virtual;
  331. {a}procedure GetContent(ALines: PUnsortedStringCollection); virtual;
  332. {a}procedure SetContent(ALines: PUnsortedStringCollection); virtual;
  333. public
  334. procedure Lock(AEditor: PCustomCodeEditor);
  335. procedure UnLock(AEditor: PCustomCodeEditor);
  336. function Locked: boolean;
  337. public
  338. { Syntax highlight }
  339. function UpdateAttrs(FromLine: sw_integer; Attrs: byte): sw_integer; virtual;
  340. function UpdateAttrsRange(FromLine, ToLine: sw_integer; Attrs: byte): sw_integer; virtual;
  341. function DoUpdateAttrs(Editor: PCustomCodeEditor; FromLine: sw_integer; Attrs: byte): sw_integer; virtual;
  342. function DoUpdateAttrsRange(Editor: PCustomCodeEditor; FromLine, ToLine: sw_integer;
  343. Attrs: byte): sw_integer; virtual;
  344. public
  345. { Undo info storage }
  346. {a}procedure AddAction(AAction: byte; AStartPos, AEndPos: TPoint; AText: string); virtual;
  347. {a}procedure AddGroupedAction(AAction : byte); virtual;
  348. {a}procedure CloseGroupedAction(AAction : byte); virtual;
  349. {a}function GetUndoActionCount: sw_integer; virtual;
  350. {a}function GetRedoActionCount: sw_integer; virtual;
  351. procedure UpdateUndoRedo(cm : word; action : byte);virtual;
  352. end;
  353. TCaseAction = (caToLowerCase,caToUpperCase,caToggleCase);
  354. TCustomCodeEditor = object(TScroller)
  355. SelStart : TPoint;
  356. SelEnd : TPoint;
  357. Highlight : TRect;
  358. CurPos : TPoint;
  359. LockFlag : integer;
  360. NoSelect : Boolean;
  361. AlwaysShowScrollBars: boolean;
  362. public
  363. { constructor Load(var S: TStream);
  364. procedure Store(var S: TStream);}
  365. procedure ConvertEvent(var Event: TEvent); virtual;
  366. procedure HandleEvent(var Event: TEvent); virtual;
  367. procedure SetState(AState: Word; Enable: Boolean); virtual;
  368. procedure LocalMenu(P: TPoint); virtual;
  369. function GetLocalMenu: PMenu; virtual;
  370. function GetCommandTarget: PView; virtual;
  371. function CreateLocalMenuView(var Bounds: TRect; M: PMenu): PMenuPopup; virtual;
  372. function GetPalette: PPalette; virtual;
  373. public
  374. procedure Draw; virtual;
  375. procedure DrawCursor; virtual;
  376. procedure DrawIndicator; virtual;
  377. public
  378. {a}function GetFlags: longint; virtual;
  379. {a}procedure SetFlags(AFlags: longint); virtual;
  380. {a}function GetModified: boolean; virtual;
  381. {a}procedure SetModified(AModified: boolean); virtual;
  382. {a}function GetStoreUndo: boolean; virtual;
  383. {a}procedure SetStoreUndo(AStore: boolean); virtual;
  384. {a}function GetSyntaxCompleted: boolean; virtual;
  385. {a}procedure SetSyntaxCompleted(SC: boolean); virtual;
  386. {a}function GetLastSyntaxedLine: sw_integer; virtual;
  387. {a}procedure SetLastSyntaxedLine(ALine: sw_integer); virtual;
  388. function IsFlagSet(AFlag: longint): boolean;
  389. {a}function GetTabSize: integer; virtual;
  390. {a}procedure SetTabSize(ATabSize: integer); virtual;
  391. {a}function IsReadOnly: boolean; virtual;
  392. {a}function IsClipboard: Boolean; virtual;
  393. {a}function GetInsertMode: boolean; virtual;
  394. {a}procedure SetInsertMode(InsertMode: boolean); virtual;
  395. procedure SetCurPtr(X,Y: sw_integer); virtual;
  396. procedure GetSelectionArea(var StartP,EndP: TPoint); virtual;
  397. procedure SetSelection(A, B: TPoint); virtual;
  398. procedure SetHighlight(A, B: TPoint); virtual;
  399. procedure ChangeCaseArea(StartP,EndP: TPoint; CaseAction: TCaseAction); virtual;
  400. procedure SetLineFlagState(LineNo: sw_integer; Flags: longint; ASet: boolean);
  401. procedure SetLineFlagExclusive(Flags: longint; LineNo: sw_integer);
  402. procedure Update; virtual;
  403. procedure ScrollTo(X, Y: sw_Integer);
  404. procedure TrackCursor(Center: boolean); virtual;
  405. procedure Lock; virtual;
  406. procedure UnLock; virtual;
  407. public
  408. { Text & info storage abstraction }
  409. {a}function GetLineCount: sw_integer; virtual;
  410. {a}function GetLine(LineNo: sw_integer): PCustomLine; virtual;
  411. {a}function CharIdxToLinePos(Line,CharIdx: sw_integer): sw_integer; virtual;
  412. {a}function LinePosToCharIdx(Line,X: sw_integer): sw_integer; virtual;
  413. {a}function GetLineText(I: sw_integer): string; virtual;
  414. {a}procedure SetDisplayText(I: sw_integer;const S: string); virtual;
  415. {a}function GetDisplayText(I: sw_integer): string; virtual;
  416. {a}procedure SetLineText(I: sw_integer;const S: string); virtual;
  417. {a}procedure GetDisplayTextFormat(I: sw_integer;var DT,DF:string); virtual;
  418. {a}function GetLineFormat(I: sw_integer): string; virtual;
  419. {a}procedure SetLineFormat(I: sw_integer;const S: string); virtual;
  420. {a}procedure DeleteAllLines; virtual;
  421. {a}procedure DeleteLine(I: sw_integer); virtual;
  422. {a}procedure InsertLine(LineNo: sw_integer; const S: string); virtual;
  423. {a}procedure AddLine(const S: string); virtual;
  424. {a}function GetErrorMessage: string; virtual;
  425. {a}procedure SetErrorMessage(const S: string); virtual;
  426. {a}procedure AdjustSelection(DeltaX, DeltaY: sw_integer);
  427. {a}procedure AdjustSelectionPos(CurPosX, CurPosY: sw_integer; DeltaX, DeltaY: sw_integer);
  428. {a}procedure GetContent(ALines: PUnsortedStringCollection); virtual;
  429. {a}procedure SetContent(ALines: PUnsortedStringCollection); virtual;
  430. {a}function LoadFromStream(Stream: PStream): boolean; virtual;
  431. {a}function SaveToStream(Stream: PStream): boolean; virtual;
  432. {a}function SaveAreaToStream(Stream: PStream; StartP,EndP: TPoint): boolean;virtual;
  433. function LoadFromFile(const AFileName: string): boolean; virtual;
  434. function SaveToFile(const AFileName: string): boolean; virtual;
  435. public
  436. {a}function InsertFrom(Editor: PCustomCodeEditor): Boolean; virtual;
  437. {a}function InsertText(const S: string): Boolean; virtual;
  438. public
  439. procedure FlagsChanged(OldFlags: longint); virtual;
  440. {a}procedure BindingsChanged; virtual;
  441. procedure ContentsChanged; virtual;
  442. procedure LimitsChanged; virtual;
  443. procedure ModifiedChanged; virtual;
  444. procedure PositionChanged; virtual;
  445. procedure TabSizeChanged; virtual;
  446. procedure SyntaxStateChanged; virtual;
  447. procedure StoreUndoChanged; virtual;
  448. procedure SelectionChanged; virtual;
  449. procedure HighlightChanged; virtual;
  450. {a}procedure DoLimitsChanged; virtual;
  451. public
  452. { Syntax highlight support }
  453. {a}function GetSpecSymbolCount(SpecClass: TSpecSymbolClass): integer; virtual;
  454. {a}function GetSpecSymbol(SpecClass: TSpecSymbolClass; Index: integer): string; virtual;
  455. {a}function IsReservedWord(const S: string): boolean; virtual;
  456. public
  457. { CodeTemplate support }
  458. {a}function TranslateCodeTemplate(const Shortcut: string; ALines: PUnsortedStringCollection): boolean; virtual;
  459. { CodeComplete support }
  460. {a}function CompleteCodeWord(const WordS: string; var Text: string): boolean; virtual;
  461. {a}function GetCodeCompleteWord: string; virtual;
  462. {a}procedure SetCodeCompleteWord(const S: string); virtual;
  463. {a}function GetCodeCompleteFrag: string; virtual;
  464. {a}procedure SetCodeCompleteFrag(const S: string); virtual;
  465. function GetCompleteState: TCompleteState; virtual;
  466. procedure SetCompleteState(AState: TCompleteState); virtual;
  467. procedure ClearCodeCompleteWord; virtual;
  468. public
  469. { Syntax highlight }
  470. {a}function UpdateAttrs(FromLine: sw_integer; Attrs: byte): sw_integer; virtual;
  471. {a}function UpdateAttrsRange(FromLine, ToLine: sw_integer; Attrs: byte): sw_integer; virtual;
  472. public
  473. { Undo info storage }
  474. {a}procedure AddAction(AAction: byte; AStartPos, AEndPos: TPoint; AText: string); virtual;
  475. {a}procedure AddGroupedAction(AAction : byte); virtual;
  476. {a}procedure CloseGroupedAction(AAction : byte); virtual;
  477. {a}function GetUndoActionCount: sw_integer; virtual;
  478. {a}function GetRedoActionCount: sw_integer; virtual;
  479. {$ifdef TP}public{$else}protected{$endif}
  480. LastLocalCmd: word;
  481. KeyState : Integer;
  482. Bookmarks : array[0..9] of TEditorBookmark;
  483. DrawCalled,
  484. DrawCursorCalled: boolean;
  485. CurEvent : PEvent;
  486. procedure DrawLines(FirstLine: sw_integer);
  487. function Overwrite: boolean;
  488. function IsModal: boolean;
  489. procedure CheckSels;
  490. procedure CodeCompleteCheck;
  491. procedure CodeCompleteApply;
  492. procedure CodeCompleteCancel;
  493. procedure UpdateUndoRedo(cm : word; action : byte);
  494. procedure HideHighlight;
  495. function ShouldExtend: boolean;
  496. function ValidBlock: boolean;
  497. public
  498. { Editor primitives }
  499. procedure SelectAll(Enable: boolean); virtual;
  500. public
  501. { Editor commands }
  502. SearchRunCount: integer;
  503. InASCIIMode: boolean;
  504. procedure Indent; virtual;
  505. procedure CharLeft; virtual;
  506. procedure CharRight; virtual;
  507. procedure WordLeft; virtual;
  508. procedure WordRight; virtual;
  509. procedure LineStart; virtual;
  510. procedure LineEnd; virtual;
  511. procedure LineUp; virtual;
  512. procedure LineDown; virtual;
  513. procedure PageUp; virtual;
  514. procedure PageDown; virtual;
  515. procedure TextStart; virtual;
  516. procedure TextEnd; virtual;
  517. procedure WindowStart; virtual;
  518. procedure WindowEnd; virtual;
  519. procedure JumpSelStart; virtual;
  520. procedure JumpSelEnd; virtual;
  521. procedure JumpMark(MarkIdx: integer); virtual;
  522. procedure DefineMark(MarkIdx: integer); virtual;
  523. procedure JumpToLastCursorPos; virtual;
  524. procedure FindMatchingDelimiter(ScanForward: boolean); virtual;
  525. procedure UpperCase; virtual;
  526. procedure LowerCase; virtual;
  527. procedure WordLowerCase; virtual;
  528. procedure WordUpperCase; virtual;
  529. procedure InsertOptions; virtual;
  530. procedure ToggleCase; virtual;
  531. function InsertNewLine: Sw_integer; virtual;
  532. procedure BreakLine; virtual;
  533. procedure BackSpace; virtual;
  534. procedure DelChar; virtual;
  535. procedure DelWord; virtual;
  536. procedure DelStart; virtual;
  537. procedure DelEnd; virtual;
  538. procedure DelLine; virtual;
  539. procedure InsMode; virtual;
  540. procedure StartSelect; virtual;
  541. procedure EndSelect; virtual;
  542. procedure DelSelect; virtual;
  543. procedure HideSelect; virtual;
  544. procedure CopyBlock; virtual;
  545. procedure MoveBlock; virtual;
  546. procedure IndentBlock; virtual;
  547. procedure UnindentBlock; virtual;
  548. procedure SelectWord; virtual;
  549. procedure SelectLine; virtual;
  550. procedure WriteBlock; virtual;
  551. procedure ReadBlock; virtual;
  552. procedure PrintBlock; virtual;
  553. procedure ExpandCodeTemplate; virtual;
  554. procedure AddChar(C: char); virtual;
  555. {$ifdef WinClipSupported}
  556. function ClipCopyWin: Boolean; virtual;
  557. function ClipPasteWin: Boolean; virtual;
  558. {$endif WinClipSupported}
  559. function ClipCopy: Boolean; virtual;
  560. procedure ClipCut; virtual;
  561. procedure ClipPaste; virtual;
  562. function GetCurrentWord : string;
  563. function GetCurrentWordArea(var StartP,EndP: TPoint): boolean;
  564. procedure Undo; virtual;
  565. procedure Redo; virtual;
  566. procedure Find; virtual;
  567. procedure Replace; virtual;
  568. procedure DoSearchReplace; virtual;
  569. procedure GotoLine; virtual;
  570. end;
  571. TCodeEditorDialog = function(Dialog: Integer; Info: Pointer): Word;
  572. const
  573. EOL : String[2] = {$ifdef Linux}#10;{$else}#13#10;{$endif}
  574. cmCopyWin = 240;
  575. cmPasteWin = 241;
  576. { History ID }
  577. FileId = 101;
  578. TextFindId = 105;
  579. TextReplaceID = 106;
  580. GotoID = 107;
  581. TextGrepId = 108;
  582. GrepArgsId = 109;
  583. { used for ShiftDel and ShiftIns to avoid
  584. GetShiftState to be considered for extending
  585. selection (PM) }
  586. DontConsiderShiftState: boolean = false;
  587. ToClipCmds : TCommandSet = ([cmCut,cmCopy,cmCopyWin]);
  588. FromClipCmds : TCommandSet = ([cmPaste]);
  589. FromWinClipCmds : TCommandSet = ([cmPasteWin]);
  590. NulClipCmds : TCommandSet = ([cmClear]);
  591. UndoCmd : TCommandSet = ([cmUndo]);
  592. RedoCmd : TCommandSet = ([cmRedo]);
  593. function ExtractTabs(S: string; TabSize: Sw_integer): string;
  594. function StdEditorDialog(Dialog: Integer; Info: Pointer): word;
  595. const
  596. DefaultSaveExt : string[12] = '.pas';
  597. FileDir : DirStr = '';
  598. EditorDialog : TCodeEditorDialog = StdEditorDialog;
  599. Clipboard : PCustomCodeEditor = nil;
  600. FindStr : String[FindStrSize] = '';
  601. ReplaceStr : String[FindStrSize] = '';
  602. FindFlags : word = ffPromptOnReplace;
  603. WhiteSpaceChars : set of char = [#0,#32,#255];
  604. TabChars : set of char = [#9];
  605. HashChars : set of char = ['#'];
  606. AlphaChars : set of char = ['A'..'Z','a'..'z','_'];
  607. NumberChars : set of char = ['0'..'9'];
  608. RealNumberChars : set of char = ['E','e','.'{,'+','-'}];
  609. procedure RegisterWEditor;
  610. implementation
  611. uses
  612. MsgBox,Dialogs,App,StdDlg,Validate,
  613. {$ifdef WinClipSupported}
  614. Strings,WinClip,
  615. {$endif WinClipSupported}
  616. WConsts,WViews,WCEdit;
  617. type
  618. TFindDialogRec = packed record
  619. Find : String[FindStrSize];
  620. Options : Word{longint};
  621. { checkboxes need 32 bits PM }
  622. { reverted to word in dialogs.TCluster for TP compatibility (PM) }
  623. { anyhow its complete nonsense : you can only have 16 fields
  624. but use a longint to store it !! }
  625. Direction: word;{ and tcluster has word size }
  626. Scope : word;
  627. Origin : word;
  628. end;
  629. TReplaceDialogRec = packed record
  630. Find : String[FindStrSize];
  631. Replace : String[FindStrSize];
  632. Options : Word{longint};
  633. Direction: word;
  634. Scope : word;
  635. Origin : word;
  636. end;
  637. TGotoLineDialogRec = packed record
  638. LineNo : string[5];
  639. Lines : sw_integer;
  640. end;
  641. const
  642. kbShift = kbLeftShift+kbRightShift;
  643. const
  644. FirstKeyCount = 41;
  645. FirstKeys: array[0..FirstKeyCount * 2] of Word = (FirstKeyCount,
  646. Ord(^A), cmWordLeft, Ord(^B), cmJumpLine, Ord(^C), cmPageDown,
  647. Ord(^D), cmCharRight, Ord(^E), cmLineUp,
  648. Ord(^F), cmWordRight, Ord(^G), cmDelChar,
  649. Ord(^H), cmBackSpace, Ord(^J), cmExpandCodeTemplate,
  650. Ord(^K), $FF02, Ord(^L), cmSearchAgain,
  651. Ord(^M), cmNewLine, Ord(^N), cmBreakLine,
  652. Ord(^O), $FF03,
  653. Ord(^P), cmASCIIChar, Ord(^Q), $FF01,
  654. Ord(^R), cmPageUp, Ord(^S), cmCharLeft,
  655. Ord(^T), cmDelWord, Ord(^U), cmUndo,
  656. Ord(^V), cmInsMode, Ord(^X), cmLineDown,
  657. Ord(^Y), cmDelLine, kbLeft, cmCharLeft,
  658. kbRight, cmCharRight, kbCtrlLeft, cmWordLeft,
  659. kbCtrlRight, cmWordRight, kbHome, cmLineStart,
  660. kbEnd, cmLineEnd, kbUp, cmLineUp,
  661. kbDown, cmLineDown, kbPgUp, cmPageUp,
  662. kbPgDn, cmPageDown, kbCtrlPgUp, cmTextStart,
  663. kbCtrlPgDn, cmTextEnd, kbIns, cmInsMode,
  664. kbDel, cmDelChar, kbShiftIns, cmPaste,
  665. kbShiftDel, cmCut, kbCtrlIns, cmCopy,
  666. kbCtrlDel, cmClear);
  667. QuickKeyCount = 29;
  668. QuickKeys: array[0..QuickKeyCount * 2] of Word = (QuickKeyCount,
  669. Ord('A'), cmReplace, Ord('C'), cmTextEnd,
  670. Ord('D'), cmLineEnd, Ord('F'), cmFind,
  671. Ord('H'), cmDelStart, Ord('R'), cmTextStart,
  672. Ord('S'), cmLineStart, Ord('Y'), cmDelEnd,
  673. Ord('G'), cmJumpLine, Ord('A'), cmReplace,
  674. Ord('B'), cmSelStart, Ord('K'), cmSelEnd,
  675. Ord('P'), cmLastCursorPos,
  676. Ord('E'), cmWindowStart, Ord('T'), cmWindowStart,
  677. Ord('U'), cmWindowEnd, Ord('X'), cmWindowEnd,
  678. Ord('['), cmFindMatchingDelimiter, Ord(']'), cmFindMatchingDelimiterBack,
  679. Ord('0'), cmJumpMark0, Ord('1'), cmJumpMark1, Ord('2'), cmJumpMark2,
  680. Ord('3'), cmJumpMark3, Ord('4'), cmJumpMark4, Ord('5'), cmJumpMark5,
  681. Ord('6'), cmJumpMark6, Ord('7'), cmJumpMark7, Ord('8'), cmJumpMark8,
  682. Ord('9'), cmJumpMark9);
  683. BlockKeyCount = 29;
  684. BlockKeys: array[0..BlockKeyCount * 2] of Word = (BlockKeyCount,
  685. Ord('B'), cmStartSelect, Ord('C'), cmCopyBlock,
  686. Ord('H'), cmHideSelect, Ord('K'), cmEndSelect,
  687. Ord('Y'), cmDelSelect, Ord('V'), cmMoveBlock,
  688. Ord('I'), cmIndentBlock, Ord('U'), cmUnindentBlock,
  689. Ord('T'), cmSelectWord, Ord('L'), cmSelectLine,
  690. Ord('W'), cmWriteBlock, Ord('R'), cmReadBlock,
  691. Ord('P'), cmPrintBlock,
  692. Ord('N'), cmUpperCase, Ord('O'), cmLowerCase,
  693. Ord('D'), cmActivateMenu,
  694. Ord('E'), cmWordLowerCase, Ord('F'), cmWordUpperCase,
  695. Ord('S'), cmSave,
  696. Ord('0'), cmSetMark0, Ord('1'), cmSetMark1, Ord('2'), cmSetMark2,
  697. Ord('3'), cmSetMark3, Ord('4'), cmSetMark4, Ord('5'), cmSetMark5,
  698. Ord('6'), cmSetMark6, Ord('7'), cmSetMark7, Ord('8'), cmSetMark8,
  699. Ord('9'), cmSetMark9);
  700. MiscKeyCount = 6;
  701. MiscKeys: array[0..MiscKeyCount * 2] of Word = (MiscKeyCount,
  702. Ord('A'), cmOpenAtCursor, Ord('B'), cmBrowseAtCursor,
  703. Ord('G'), cmJumpLine, Ord('O'), cmInsertOptions,
  704. Ord('U'), cmToggleCase, Ord('L'), cmSelectLine);
  705. KeyMap: array[0..3] of Pointer = (@FirstKeys, @QuickKeys, @BlockKeys, @MiscKeys);
  706. function ScanKeyMap(KeyMap: Pointer; KeyCode: Word): Word;
  707. type
  708. pword = ^word;
  709. var
  710. p : pword;
  711. count : sw_word;
  712. begin
  713. p:=keymap;
  714. count:=p^;
  715. inc(p);
  716. while (count>0) do
  717. begin
  718. if (lo(p^)=lo(keycode)) and
  719. ((hi(p^)=0) or (hi(p^)=hi(keycode))) then
  720. begin
  721. inc(p);
  722. scankeymap:=p^;
  723. Exit;
  724. end;
  725. inc(p,2);
  726. dec(count);
  727. end;
  728. scankeymap:=0;
  729. end;
  730. function IsWordSeparator(C: char): boolean;
  731. begin
  732. IsWordSeparator:=C in[' ',#0,#255,':','=','''','"','.',',','/',';','$','#','(',')','<','>','^','*','+','-','?','&','[',']'];
  733. end;
  734. {function IsSpace(C: char): boolean;
  735. begin
  736. IsSpace:=C in[' ',#0,#255];
  737. end;}
  738. function LTrim(S: string): string;
  739. begin
  740. while (length(S)>0) and (S[1] in [#0,TAB,#32]) do
  741. Delete(S,1,1);
  742. LTrim:=S;
  743. end;
  744. { TAB are not same as spaces if UseTabs is set PM }
  745. function RTrim(S: string;cut_tabs : boolean): string;
  746. begin
  747. while (length(S)>0) and
  748. ((S[length(S)] in [#0,#32]) or
  749. ((S[Length(S)]=TAB) and cut_tabs)) do
  750. Delete(S,length(S),1);
  751. RTrim:=S;
  752. end;
  753. function Trim(S: string): string;
  754. begin
  755. Trim:=RTrim(LTrim(S),true);
  756. end;
  757. function EatIO: integer;
  758. begin
  759. EatIO:=IOResult;
  760. end;
  761. function ExistsFile(const FileName: string): boolean;
  762. var f: file;
  763. Exists: boolean;
  764. begin
  765. if FileName='' then Exists:=false else
  766. begin
  767. {$I-}
  768. Assign(f,FileName);
  769. Reset(f,1);
  770. Exists:=EatIO=0;
  771. Close(f);
  772. EatIO;
  773. {$I+}
  774. end;
  775. ExistsFile:=Exists;
  776. end;
  777. function Max(A,B: longint): longint;
  778. begin
  779. if A>B then Max:=A else Max:=B;
  780. end;
  781. function Min(A,B: longint): longint;
  782. begin
  783. if A<B then Min:=A else Min:=B;
  784. end;
  785. function StrToInt(const S: string): longint;
  786. var L: longint;
  787. C: integer;
  788. begin
  789. Val(S,L,C); if C<>0 then L:=-1;
  790. StrToInt:=L;
  791. end;
  792. function RExpand(const S: string; MinLen: byte): string;
  793. begin
  794. if length(S)<MinLen then
  795. RExpand:=S+CharStr(' ',MinLen-length(S))
  796. else
  797. RExpand:=S;
  798. end;
  799. function upper(const s : string) : string;
  800. var
  801. i : Sw_word;
  802. begin
  803. for i:=1 to length(s) do
  804. if s[i] in ['a'..'z'] then
  805. upper[i]:=char(byte(s[i])-32)
  806. else
  807. upper[i]:=s[i];
  808. upper[0]:=s[0];
  809. end;
  810. type TPosOfs = {$ifdef TP}longint{$endif}{$ifdef FPC}comp{$endif};
  811. function PosToOfs(const X,Y: sw_integer): TPosOfs;
  812. type TPosRec = record LoI, HiI: sw_integer; end;
  813. var C: TPosRec;
  814. begin
  815. C.LoI:=X; C.HiI:=Y;
  816. PosToOfs:=TPosOfs(C);
  817. end;
  818. function PosToOfsP(const P: TPoint): TPosOfs;
  819. begin
  820. PosToOfsP:=PosToOfs(P.X,P.Y);
  821. end;
  822. function PointOfs(P: TPoint): TPosOfs;
  823. begin
  824. PointOfs:={longint(P.Y)*MaxLineLength+P.X}PosToOfsP(P);
  825. end;
  826. {$ifndef Undo}
  827. function NewEditorAction(AAction: byte; AStartPos, AEndPos: TPoint; AText: string): PEditorAction;
  828. var P: PEditorAction;
  829. begin
  830. New(P); FillChar(P^,SizeOf(P^),0);
  831. with P^ do
  832. begin
  833. Action:=AAction;
  834. StartPos:=AStartPos; EndPos:=AEndPos;
  835. Text:=NewStr(AText);
  836. end;
  837. NewEditorAction:=P;
  838. end;
  839. procedure DisposeEditorAction(P: PEditorAction);
  840. begin
  841. if P<>nil then
  842. begin
  843. if P^.Text<>nil then DisposeStr(P^.Text); P^.Text:=nil;
  844. Dispose(P);
  845. end;
  846. end;
  847. {$endif ndef Undo}
  848. function ExtractTabs(S: string; TabSize: Sw_integer): string;
  849. var
  850. P,PAdd: Sw_Word;
  851. begin
  852. p:=0;
  853. while p<length(s) do
  854. begin
  855. inc(p);
  856. if s[p]=TAB then
  857. begin
  858. PAdd:=TabSize-((p-1) mod TabSize);
  859. s:=copy(S,1,P-1)+CharStr(' ',PAdd)+copy(S,P+1,High(s));
  860. inc(P,PAdd-1);
  861. end;
  862. end;
  863. ExtractTabs:=S;
  864. end;
  865. {function CompressUsingTabs(S: string; TabSize: byte): string;
  866. var TabS: string;
  867. P: byte;
  868. begin
  869. TabS:=CharStr(' ',TabSize);
  870. repeat
  871. P:=Pos(TabS,S);
  872. if P>0 then
  873. S:=copy(S,1,P-1)+TAB+copy(S,P+TabSize,High(S));
  874. until P=0;
  875. CompressUsingTabs:=S;
  876. end;}
  877. {*****************************************************************************
  878. Forward/Backward Scanning
  879. *****************************************************************************}
  880. Const
  881. {$ifndef FPC}
  882. MaxBufLength = $7f00;
  883. NotFoundValue = -1;
  884. {$else}
  885. MaxBufLength = $7fffff00;
  886. NotFoundValue = -1;
  887. {$endif}
  888. Type
  889. Btable = Array[0..255] of Byte;
  890. Procedure BMFMakeTable(const s:string; Var t : Btable);
  891. Var
  892. x : sw_integer;
  893. begin
  894. FillChar(t,sizeof(t),length(s));
  895. For x := length(s) downto 1 do
  896. if (t[ord(s[x])] = length(s)) then
  897. t[ord(s[x])] := length(s) - x;
  898. end;
  899. function BMFScan(var Block; Size: Sw_Word;const Str: String;const bt:BTable): Sw_Integer;
  900. Var
  901. buffer : Array[0..MaxBufLength-1] of Byte Absolute block;
  902. s2 : String;
  903. len,
  904. numb : Sw_Word;
  905. found : Boolean;
  906. begin
  907. len:=length(str);
  908. if len>size then
  909. begin
  910. BMFScan := NotFoundValue;
  911. exit;
  912. end;
  913. s2[0]:=chr(len); { sets the length to that of the search String }
  914. found:=False;
  915. numb:=pred(len);
  916. While (not found) and (numb<size) do
  917. begin
  918. { partial match }
  919. if buffer[numb] = ord(str[len]) then
  920. begin
  921. { less partial! }
  922. if buffer[numb-pred(len)] = ord(str[1]) then
  923. begin
  924. move(buffer[numb-pred(len)],s2[1],len);
  925. if (str=s2) then
  926. begin
  927. found:=true;
  928. break;
  929. end;
  930. end;
  931. inc(numb);
  932. end
  933. else
  934. inc(numb,Bt[buffer[numb]]);
  935. end;
  936. if not found then
  937. BMFScan := NotFoundValue
  938. else
  939. BMFScan := numb - pred(len);
  940. end;
  941. function BMFIScan(var Block; Size: Sw_Word;const Str: String;const bt:BTable): Sw_Integer;
  942. Var
  943. buffer : Array[0..MaxBufLength-1] of Char Absolute block;
  944. len,
  945. numb,
  946. x : Sw_Word;
  947. found : Boolean;
  948. p : pchar;
  949. c : char;
  950. begin
  951. len:=length(str);
  952. if (len=0) or (len>size) then
  953. begin
  954. BMFIScan := NotFoundValue;
  955. exit;
  956. end;
  957. found:=False;
  958. numb:=pred(len);
  959. While (not found) and (numb<size) do
  960. begin
  961. { partial match }
  962. c:=buffer[numb];
  963. if c in ['a'..'z'] then
  964. c:=chr(ord(c)-32);
  965. if (c=str[len]) then
  966. begin
  967. { less partial! }
  968. p:=@buffer[numb-pred(len)];
  969. x:=1;
  970. while (x<=len) do
  971. begin
  972. if not(((p^ in ['a'..'z']) and (chr(ord(p^)-32)=str[x])) or
  973. (p^=str[x])) then
  974. break;
  975. inc(p);
  976. inc(x);
  977. end;
  978. if (x>len) then
  979. begin
  980. found:=true;
  981. break;
  982. end;
  983. inc(numb);
  984. end
  985. else
  986. inc(numb,Bt[ord(c)]);
  987. end;
  988. if not found then
  989. BMFIScan := NotFoundValue
  990. else
  991. BMFIScan := numb - pred(len);
  992. end;
  993. Procedure BMBMakeTable(const s:string; Var t : Btable);
  994. Var
  995. x : sw_integer;
  996. begin
  997. FillChar(t,sizeof(t),length(s));
  998. For x := 1 to length(s)do
  999. if (t[ord(s[x])] = length(s)) then
  1000. t[ord(s[x])] := x-1;
  1001. end;
  1002. function BMBScan(var Block; Size: Sw_Word;const Str: String;const bt:BTable): Sw_Integer;
  1003. Var
  1004. buffer : Array[0..MaxBufLength-1] of Byte Absolute block;
  1005. s2 : String;
  1006. len,
  1007. numb : Sw_integer;
  1008. found : Boolean;
  1009. begin
  1010. len:=length(str);
  1011. if len>size then
  1012. begin
  1013. BMBScan := NotFoundValue;
  1014. exit;
  1015. end;
  1016. s2[0]:=chr(len); { sets the length to that of the search String }
  1017. found:=False;
  1018. numb:=size-pred(len);
  1019. While (not found) and (numb>0) do
  1020. begin
  1021. { partial match }
  1022. if buffer[numb] = ord(str[1]) then
  1023. begin
  1024. { less partial! }
  1025. if buffer[numb+pred(len)] = ord(str[len]) then
  1026. begin
  1027. move(buffer[numb],s2[1],len);
  1028. if (str=s2) then
  1029. begin
  1030. found:=true;
  1031. break;
  1032. end;
  1033. end;
  1034. dec(numb);
  1035. end
  1036. else
  1037. dec(numb,Bt[buffer[numb]]);
  1038. end;
  1039. if not found then
  1040. BMBScan := NotFoundValue
  1041. else
  1042. BMBScan := numb;
  1043. end;
  1044. function BMBIScan(var Block; Size: Sw_Word;const Str: String;const bt:BTable): Sw_Integer;
  1045. Var
  1046. buffer : Array[0..MaxBufLength-1] of Char Absolute block;
  1047. len,
  1048. numb,
  1049. x : Sw_integer;
  1050. found : Boolean;
  1051. p : pchar;
  1052. c : char;
  1053. begin
  1054. len:=length(str);
  1055. if (len=0) or (len>size) then
  1056. begin
  1057. BMBIScan := NotFoundValue;
  1058. exit;
  1059. end;
  1060. found:=False;
  1061. numb:=size-len;
  1062. While (not found) and (numb>0) do
  1063. begin
  1064. { partial match }
  1065. c:=buffer[numb];
  1066. if c in ['a'..'z'] then
  1067. c:=chr(ord(c)-32);
  1068. if (c=str[1]) then
  1069. begin
  1070. { less partial! }
  1071. p:=@buffer[numb];
  1072. x:=1;
  1073. while (x<=len) do
  1074. begin
  1075. if not(((p^ in ['a'..'z']) and (chr(ord(p^)-32)=str[x])) or
  1076. (p^=str[x])) then
  1077. break;
  1078. inc(p);
  1079. inc(x);
  1080. end;
  1081. if (x>len) then
  1082. begin
  1083. found:=true;
  1084. break;
  1085. end;
  1086. dec(numb);
  1087. end
  1088. else
  1089. dec(numb,Bt[ord(c)]);
  1090. end;
  1091. if not found then
  1092. BMBIScan := NotFoundValue
  1093. else
  1094. BMBIScan := numb;
  1095. end;
  1096. {*****************************************************************************
  1097. PLine,TLineCollection
  1098. *****************************************************************************}
  1099. constructor TCustomLine.Init(const AText: string; AFlags: longint);
  1100. begin
  1101. inherited Init;
  1102. SetText(AText);
  1103. end;
  1104. function TCustomLine.GetText: string;
  1105. begin
  1106. Abstract; GetText:='';
  1107. end;
  1108. procedure TCustomLine.SetText(const AText: string);
  1109. begin
  1110. Abstract;
  1111. end;
  1112. function TCustomLine.GetEditorInfo(Editor: PCustomCodeEditor): PEditorLineInfo;
  1113. begin
  1114. Abstract;
  1115. GetEditorInfo:=nil;
  1116. end;
  1117. function TCustomLine.GetFlags: longint;
  1118. begin
  1119. Abstract;
  1120. GetFlags:=0;
  1121. end;
  1122. procedure TCustomLine.SetFlags(AFlags: longint);
  1123. begin
  1124. Abstract;
  1125. end;
  1126. function TCustomLine.IsFlagSet(AFlag: longint): boolean;
  1127. begin
  1128. IsFlagSet:=(GetFlags and AFlag)=AFlag;
  1129. end;
  1130. procedure TCustomLine.SetFlagState(AFlag: longint; ASet: boolean);
  1131. var N,O: longint;
  1132. begin
  1133. O:=GetFlags; N:=O;
  1134. if ASet then
  1135. N:=N or AFlag
  1136. else
  1137. N:=N and (not AFlag);
  1138. if N<>O then
  1139. SetFlags(N);
  1140. end;
  1141. procedure TCustomLine.AddEditorInfo(Index: sw_integer; AEditor: PCustomCodeEditor);
  1142. begin
  1143. { Abstract }
  1144. end;
  1145. procedure TCustomLine.RemoveEditorInfo(AEditor: PCustomCodeEditor);
  1146. begin
  1147. { Abstract }
  1148. end;
  1149. destructor TCustomLine.Done;
  1150. begin
  1151. inherited Done;
  1152. end;
  1153. function TLineCollection.At(Index: sw_Integer): PCustomLine;
  1154. begin
  1155. At:=inherited At(Index);
  1156. end;
  1157. constructor TEditorLineInfo.Init(AEditor: PCustomCodeEditor);
  1158. begin
  1159. inherited Init;
  1160. Editor:=AEditor;
  1161. end;
  1162. function TEditorLineInfo.GetFormat: string;
  1163. begin
  1164. GetFormat:=GetStr(Format);
  1165. end;
  1166. procedure TEditorLineInfo.SetFormat(const AFormat: string);
  1167. begin
  1168. SetStr(Format,AFormat);
  1169. end;
  1170. destructor TEditorLineInfo.Done;
  1171. begin
  1172. if Format<>nil then DisposeStr(Format); Format:=nil;
  1173. inherited Done;
  1174. end;
  1175. function TEditorLineInfoCollection.At(Index: sw_Integer): PEditorLineInfo;
  1176. begin
  1177. At:=inherited At(Index);
  1178. end;
  1179. function TEditorBindingCollection.At(Index: sw_Integer): PEditorBinding;
  1180. begin
  1181. At:=inherited At(Index);
  1182. end;
  1183. constructor TEditorBinding.Init(AEditor: PCustomCodeEditor);
  1184. begin
  1185. inherited Init;
  1186. Editor:=AEditor;
  1187. end;
  1188. destructor TEditorBinding.Done;
  1189. begin
  1190. inherited Done;
  1191. end;
  1192. constructor TCustomCodeEditorCore.Init;
  1193. begin
  1194. inherited Init;
  1195. New(Bindings, Init(10,10));
  1196. end;
  1197. procedure TCustomCodeEditorCore.BindEditor(AEditor: PCustomCodeEditor);
  1198. var B: PEditorBinding;
  1199. Count,I,Idx: sw_integer;
  1200. L: PCustomLine;
  1201. begin
  1202. if Assigned(AEditor)=false then Exit;
  1203. New(B, Init(AEditor));
  1204. Bindings^.Insert(B);
  1205. Idx:=Bindings^.IndexOf(B);
  1206. Count:=GetLineCount;
  1207. for I:=0 to Count-1 do
  1208. begin
  1209. L:=GetLine(I);
  1210. L^.AddEditorInfo(Idx,AEditor);
  1211. end;
  1212. BindingsChanged;
  1213. end;
  1214. procedure TCustomCodeEditorCore.UnBindEditor(AEditor: PCustomCodeEditor);
  1215. var B: PEditorBinding;
  1216. Count,I: sw_integer;
  1217. L: PCustomLine;
  1218. begin
  1219. B:=SearchBinding(AEditor);
  1220. if Assigned(B) then
  1221. begin
  1222. Count:=GetLineCount;
  1223. for I:=0 to Count-1 do
  1224. begin
  1225. L:=GetLine(I);
  1226. L^.RemoveEditorInfo(AEditor);
  1227. end;
  1228. Bindings^.Free(B);
  1229. BindingsChanged;
  1230. end;
  1231. end;
  1232. function TCustomCodeEditorCore.IsEditorBound(AEditor: PCustomCodeEditor): boolean;
  1233. begin
  1234. IsEditorBound:=SearchBinding(AEditor)<>nil;
  1235. end;
  1236. function TCustomCodeEditorCore.GetBindingCount: sw_integer;
  1237. begin
  1238. GetBindingCount:=Bindings^.Count;
  1239. end;
  1240. function TCustomCodeEditorCore.GetBindingIndex(AEditor: PCustomCodeEditor): sw_integer;
  1241. var B: PEditorBinding;
  1242. begin
  1243. B:=SearchBinding(AEditor);
  1244. GetBindingIndex:=Bindings^.IndexOf(B);
  1245. end;
  1246. function TCustomCodeEditorCore.SearchBinding(AEditor: PCustomCodeEditor): PEditorBinding;
  1247. function SearchEditor(P: PEditorBinding): boolean; {$ifndef FPC}far;{$endif}
  1248. begin
  1249. SearchEditor:=P^.Editor=AEditor;
  1250. end;
  1251. begin
  1252. SearchBinding:=Bindings^.FirstThat(@SearchEditor);
  1253. end;
  1254. function TCustomCodeEditorCore.CanDispose: boolean;
  1255. begin
  1256. CanDispose:=Assigned(Bindings) and (Bindings^.Count=0);
  1257. end;
  1258. function TCustomCodeEditorCore.GetModified: boolean;
  1259. begin
  1260. Abstract;
  1261. GetModified:=true;
  1262. end;
  1263. function TCustomCodeEditorCore.GetChangedLine: sw_integer;
  1264. begin
  1265. GetChangedLine:=ChangedLine;
  1266. end;
  1267. procedure TCustomCodeEditorCore.SetModified(AModified: boolean);
  1268. begin
  1269. Abstract;
  1270. end;
  1271. function TCustomCodeEditorCore.GetStoreUndo: boolean;
  1272. begin
  1273. Abstract;
  1274. GetStoreUndo:=false;
  1275. end;
  1276. procedure TCustomCodeEditorCore.SetStoreUndo(AStore: boolean);
  1277. begin
  1278. Abstract;
  1279. end;
  1280. function TCustomCodeEditorCore.GetSyntaxCompleted: boolean;
  1281. begin
  1282. Abstract;
  1283. GetSyntaxCompleted:=true;
  1284. end;
  1285. procedure TCustomCodeEditorCore.SetSyntaxCompleted(SC : boolean);
  1286. begin
  1287. Abstract;
  1288. end;
  1289. function TCustomCodeEditorCore.IsClipboard: Boolean;
  1290. function IsClip(P: PEditorBinding): boolean; {$ifndef FPC}far;{$endif}
  1291. begin
  1292. IsClip:=(P^.Editor=Clipboard);
  1293. end;
  1294. begin
  1295. IsClipBoard:=Bindings^.FirstThat(@IsClip)<>nil;
  1296. end;
  1297. function TCustomCodeEditorCore.GetTabSize: integer;
  1298. begin
  1299. Abstract;
  1300. GetTabSize:=0;
  1301. end;
  1302. procedure TCustomCodeEditorCore.SetTabSize(ATabSize: integer);
  1303. begin
  1304. Abstract;
  1305. end;
  1306. procedure TCustomCodeEditorCore.LimitsChanged;
  1307. begin
  1308. if Locked then
  1309. LimitsChangedCalled:=true
  1310. else
  1311. DoLimitsChanged;
  1312. end;
  1313. procedure TCustomCodeEditorCore.ContentsChanged;
  1314. begin
  1315. if Locked then
  1316. ContentsChangedCalled:=true
  1317. else
  1318. DoContentsChanged;
  1319. end;
  1320. procedure TCustomCodeEditorCore.ModifiedChanged;
  1321. begin
  1322. if Locked then
  1323. ModifiedChangedCalled:=true
  1324. else
  1325. DoModifiedChanged;
  1326. end;
  1327. procedure TCustomCodeEditorCore.TabSizeChanged;
  1328. begin
  1329. if Locked then
  1330. TabSizeChangedCalled:=true
  1331. else
  1332. DoTabSizeChanged;
  1333. end;
  1334. procedure TCustomCodeEditorCore.StoreUndoChanged;
  1335. begin
  1336. if Locked then
  1337. StoreUndoChangedCalled:=true
  1338. else
  1339. DoStoreUndoChanged;
  1340. end;
  1341. procedure TCustomCodeEditorCore.BindingsChanged;
  1342. procedure CallIt(P: PEditorBinding); {$ifndef FPC}far;{$endif}
  1343. begin
  1344. P^.Editor^.BindingsChanged;
  1345. end;
  1346. begin
  1347. Bindings^.ForEach(@CallIt);
  1348. end;
  1349. procedure TCustomCodeEditorCore.DoLimitsChanged;
  1350. procedure CallIt(P: PEditorBinding); {$ifndef FPC}far;{$endif}
  1351. begin
  1352. P^.Editor^.DoLimitsChanged;
  1353. end;
  1354. begin
  1355. Bindings^.ForEach(@CallIt);
  1356. end;
  1357. procedure TCustomCodeEditorCore.DoContentsChanged;
  1358. procedure CallIt(P: PEditorBinding); {$ifndef FPC}far;{$endif}
  1359. begin
  1360. P^.Editor^.ContentsChanged;
  1361. end;
  1362. begin
  1363. Bindings^.ForEach(@CallIt);
  1364. end;
  1365. procedure TCustomCodeEditorCore.DoModifiedChanged;
  1366. procedure CallIt(P: PEditorBinding); {$ifndef FPC}far;{$endif}
  1367. begin
  1368. P^.Editor^.ModifiedChanged;
  1369. end;
  1370. begin
  1371. Bindings^.ForEach(@CallIt);
  1372. end;
  1373. procedure TCustomCodeEditorCore.DoTabSizeChanged;
  1374. procedure CallIt(P: PEditorBinding); {$ifndef FPC}far;{$endif}
  1375. begin
  1376. P^.Editor^.TabSizeChanged;
  1377. end;
  1378. begin
  1379. Bindings^.ForEach(@CallIt);
  1380. end;
  1381. procedure TCustomCodeEditorCore.UpdateUndoRedo(cm : word; action : byte);
  1382. procedure CallIt(P: PEditorBinding); {$ifndef FPC}far;{$endif}
  1383. begin
  1384. if (P^.Editor^.State and sfActive)<>0 then
  1385. begin
  1386. P^.Editor^.UpdateUndoRedo(cm,action);
  1387. if cm=cmUndo then
  1388. begin
  1389. P^.Editor^.SetCmdState(UndoCmd,true);
  1390. P^.Editor^.SetCmdState(RedoCmd,false);
  1391. Message(Application,evBroadcast,cmCommandSetChanged,nil);
  1392. end;
  1393. end;
  1394. end;
  1395. begin
  1396. Bindings^.ForEach(@CallIt);
  1397. end;
  1398. procedure TCustomCodeEditorCore.DoStoreUndoChanged;
  1399. procedure CallIt(P: PEditorBinding); {$ifndef FPC}far;{$endif}
  1400. begin
  1401. P^.Editor^.StoreUndoChanged;
  1402. end;
  1403. begin
  1404. Bindings^.ForEach(@CallIt);
  1405. end;
  1406. procedure TCustomCodeEditorCore.DoSyntaxStateChanged;
  1407. procedure CallIt(P: PEditorBinding); {$ifndef FPC}far;{$endif}
  1408. begin
  1409. P^.Editor^.SyntaxStateChanged;
  1410. end;
  1411. begin
  1412. Bindings^.ForEach(@CallIt);
  1413. end;
  1414. function TCustomCodeEditorCore.GetLastVisibleLine : sw_integer;
  1415. var
  1416. y : sw_integer;
  1417. procedure CallIt(P: PEditorBinding); {$ifndef FPC}far;{$endif}
  1418. begin
  1419. if y < P^.Editor^.Delta.Y+P^.Editor^.Size.Y then
  1420. y:=P^.Editor^.Delta.Y+P^.Editor^.Size.Y;
  1421. end;
  1422. begin
  1423. y:=0;
  1424. Bindings^.ForEach(@CallIt);
  1425. GetLastVisibleLine:=y;
  1426. end;
  1427. function TCustomCodeEditorCore.SaveToStream(Editor: PCustomCodeEditor; Stream: PStream): boolean;
  1428. var A,B: TPoint;
  1429. begin
  1430. A.Y:=0; A.X:=0;
  1431. B.Y:=GetLineCount-1;
  1432. if GetLineCount>0 then
  1433. B.X:=length(GetDisplayText(B.Y))
  1434. else
  1435. B.X:=0;
  1436. SaveToStream:=SaveAreaToStream(Editor,Stream,A,B);
  1437. end;
  1438. procedure TCustomCodeEditorCore.ISetLineFlagState(Binding: PEditorBinding; LineNo: sw_integer; Flag: longint; ASet: boolean);
  1439. begin
  1440. Abstract;
  1441. end;
  1442. procedure TCustomCodeEditorCore.IGetDisplayTextFormat(Binding: PEditorBinding; LineNo: sw_integer;var DT,DF:string);
  1443. begin
  1444. Abstract;
  1445. end;
  1446. function TCustomCodeEditorCore.IGetLineFormat(Binding: PEditorBinding; LineNo: sw_integer): string;
  1447. begin
  1448. Abstract;
  1449. IGetLineFormat:='';
  1450. end;
  1451. procedure TCustomCodeEditorCore.ISetLineFormat(Binding: PEditorBinding; LineNo: sw_integer;const S: string);
  1452. begin
  1453. Abstract;
  1454. end;
  1455. function TCustomCodeEditorCore.CharIdxToLinePos(Line,CharIdx: sw_integer): sw_integer;
  1456. var S: string;
  1457. TabSize,CP,RX: sw_integer;
  1458. begin
  1459. S:=GetLineText(Line);
  1460. TabSize:=GetTabSize;
  1461. CP:=1; RX:=0;
  1462. while {(CP<=length(S)) and }(CP<=CharIdx) do
  1463. begin
  1464. if (CP<=length(S)) and (S[CP]=TAB) then
  1465. Inc(RX,GetTabSize-(RX mod TabSize))
  1466. else
  1467. Inc(RX);
  1468. Inc(CP);
  1469. end;
  1470. CharIdxToLinePos:=RX-1;
  1471. end;
  1472. function TCustomCodeEditorCore.LinePosToCharIdx(Line,X: sw_integer): sw_integer;
  1473. var S: string;
  1474. TabSize,CP,RX: sw_integer;
  1475. begin
  1476. TabSize:=GetTabSize;
  1477. S:=GetLineText(Line);
  1478. if S='' then
  1479. CP:=0
  1480. else
  1481. begin
  1482. CP:=0; RX:=0;
  1483. while (RX<=X) and (CP<=length(S)) do
  1484. begin
  1485. Inc(CP);
  1486. if S[CP]=TAB then
  1487. Inc(RX,TabSize-(RX mod TabSize))
  1488. else
  1489. Inc(RX);
  1490. end;
  1491. end;
  1492. LinePosToCharIdx:=CP;
  1493. end;
  1494. function TCustomCodeEditorCore.GetLineCount: sw_integer;
  1495. begin
  1496. Abstract;
  1497. GetLineCount:=0;
  1498. end;
  1499. function TCustomCodeEditorCore.GetLine(LineNo: sw_integer): PCustomLine;
  1500. begin
  1501. Abstract;
  1502. GetLine:=nil;
  1503. end;
  1504. function TCustomCodeEditorCore.GetLineText(LineNo: sw_integer): string;
  1505. begin
  1506. Abstract;
  1507. GetLineText:='';
  1508. end;
  1509. procedure TCustomCodeEditorCore.SetDisplayText(I: sw_integer;const S: string);
  1510. begin
  1511. Abstract;
  1512. end;
  1513. function TCustomCodeEditorCore.GetDisplayText(I: sw_integer): string;
  1514. begin
  1515. Abstract;
  1516. GetDisplayText:='';
  1517. end;
  1518. procedure TCustomCodeEditorCore.SetLineText(I: sw_integer;const S: string);
  1519. begin
  1520. Abstract;
  1521. end;
  1522. procedure TCustomCodeEditorCore.GetDisplayTextFormat(Editor: PCustomCodeEditor; I: sw_integer;var DT,DF:string);
  1523. begin
  1524. IGetDisplayTextFormat(SearchBinding(Editor),I,DT,DF);
  1525. end;
  1526. function TCustomCodeEditorCore.GetLineFormat(Editor: PCustomCodeEditor; I: sw_integer): string;
  1527. begin
  1528. GetLineFormat:=IGetLineFormat(SearchBinding(Editor),I);
  1529. end;
  1530. procedure TCustomCodeEditorCore.SetLineFormat(Editor: PCustomCodeEditor; I: sw_integer; const S: string);
  1531. begin
  1532. ISetLineFormat(SearchBinding(Editor),I,S);
  1533. end;
  1534. procedure TCustomCodeEditorCore.DeleteAllLines;
  1535. begin
  1536. Abstract;
  1537. end;
  1538. procedure TCustomCodeEditorCore.DeleteLine(I: sw_integer);
  1539. begin
  1540. Abstract;
  1541. end;
  1542. procedure TCustomCodeEditorCore.InsertLine(LineNo: sw_integer; const S: string);
  1543. begin
  1544. Abstract;
  1545. end;
  1546. procedure TCustomCodeEditorCore.AddLine(const S: string);
  1547. begin
  1548. Abstract;
  1549. end;
  1550. procedure TCustomCodeEditorCore.GetContent(ALines: PUnsortedStringCollection);
  1551. begin
  1552. Abstract;
  1553. end;
  1554. procedure TCustomCodeEditorCore.SetContent(ALines: PUnsortedStringCollection);
  1555. begin
  1556. Abstract;
  1557. end;
  1558. function TCustomCodeEditorCore.Locked: boolean;
  1559. begin
  1560. Locked:=LockFlag>0;
  1561. end;
  1562. procedure TCustomCodeEditorCore.Lock(AEditor: PCustomCodeEditor);
  1563. begin
  1564. Inc(LockFlag);
  1565. end;
  1566. procedure TCustomCodeEditorCore.UnLock(AEditor: PCustomCodeEditor);
  1567. begin
  1568. {$ifdef DEBUG}
  1569. if LockFlag=0 then
  1570. Bug('negative lockflag',nil)
  1571. else
  1572. {$endif DEBUG}
  1573. Dec(LockFlag);
  1574. if (LockFlag>0) then
  1575. Exit;
  1576. if LimitsChangedCalled then
  1577. begin
  1578. DoLimitsChanged;
  1579. LimitsChangedCalled:=false;
  1580. end;
  1581. if ModifiedChangedCalled then
  1582. begin
  1583. DoModifiedChanged;
  1584. ModifiedChangedCalled:=false;
  1585. end;
  1586. if TabSizeChangedCalled then
  1587. begin
  1588. DoTabSizeChanged;
  1589. TabSizeChangedCalled:=false;
  1590. end;
  1591. if StoreUndoChangedCalled then
  1592. begin
  1593. DoStoreUndoChanged;
  1594. StoreUndoChangedCalled:=false;
  1595. end;
  1596. if ContentsChangedCalled then
  1597. begin
  1598. DoContentsChanged;
  1599. ContentsChangedCalled:=false;
  1600. end;
  1601. end;
  1602. function TCustomCodeEditorCore.UpdateAttrs(FromLine: sw_integer; Attrs: byte): sw_integer;
  1603. var MinLine: sw_integer;
  1604. procedure CallIt(P: PEditorBinding); {$ifndef FPC}far;{$endif}
  1605. var I: sw_integer;
  1606. begin
  1607. I:=DoUpdateAttrs(P^.Editor,FromLine,Attrs);
  1608. if (I<MinLine) or (MinLine=-1) then MinLine:=I;
  1609. end;
  1610. begin
  1611. MinLine:=-1;
  1612. Bindings^.ForEach(@CallIt);
  1613. UpdateAttrs:=MinLine;
  1614. end;
  1615. function TCustomCodeEditorCore.UpdateAttrsRange(FromLine, ToLine: sw_integer; Attrs: byte): sw_integer;
  1616. var MinLine: sw_integer;
  1617. procedure CallIt(P: PEditorBinding); {$ifndef FPC}far;{$endif}
  1618. var I: sw_integer;
  1619. begin
  1620. I:=DoUpdateAttrsRange(P^.Editor,FromLine,ToLine,Attrs);
  1621. if (I<MinLine) or (MinLine=-1) then MinLine:=I;
  1622. end;
  1623. begin
  1624. MinLine:=-1;
  1625. Bindings^.ForEach(@CallIt);
  1626. UpdateAttrsRange:=MinLine;
  1627. end;
  1628. function TCustomCodeEditorCore.DoUpdateAttrs(Editor: PCustomCodeEditor; FromLine: sw_integer; Attrs: byte): sw_integer;
  1629. type
  1630. TCharClass = (ccWhiteSpace,ccTab,ccAlpha,ccNumber,ccRealNumber,ccHash,ccSymbol);
  1631. var
  1632. SymbolIndex: Sw_integer;
  1633. CurrentCommentType : Byte;
  1634. FirstCC,LastCC: TCharClass;
  1635. InAsm,InComment,InSingleLineComment,InDirective,InString: boolean;
  1636. X,ClassStart: Sw_integer;
  1637. SymbolConcat: string;
  1638. LineText,Format: string;
  1639. function MatchSymbol(const What, S: string): boolean;
  1640. var Match: boolean;
  1641. begin
  1642. Match:=false;
  1643. if length(What)>=length(S) then
  1644. if copy(What,1+length(What)-length(S),length(S))=S then
  1645. Match:=true;
  1646. MatchSymbol:=Match;
  1647. end;
  1648. var MatchedSymbol: boolean;
  1649. MatchingSymbol: string;
  1650. type TPartialType = (pmNone,pmLeft,pmRight,pmAny);
  1651. function MatchesAnySpecSymbol(What: string; SClass: TSpecSymbolClass; PartialMatch: TPartialType;
  1652. CaseInsensitive: boolean): boolean;
  1653. var S: string;
  1654. I: Sw_integer;
  1655. Match,Found: boolean;
  1656. begin
  1657. Found:=false;
  1658. if CaseInsensitive then
  1659. What:=UpcaseStr(What);
  1660. if What<>'' then
  1661. for I:=1 to Editor^.GetSpecSymbolCount(SClass) do
  1662. begin
  1663. SymbolIndex:=I;
  1664. S:=Editor^.GetSpecSymbol(SClass,I-1);
  1665. if (length(What)<length(S)) or
  1666. ((PartialMatch=pmNone) and (length(S)<>length(What)))
  1667. then
  1668. Match:=false
  1669. else
  1670. begin
  1671. if CaseInsensitive then
  1672. S:=UpcaseStr(S);
  1673. case PartialMatch of
  1674. pmNone : Match:=What=S;
  1675. pmRight:
  1676. Match:=copy(What,length(What)-length(S)+1,length(S))=S;
  1677. else Match:=MatchSymbol(What,S);
  1678. end;
  1679. end;
  1680. if Match then
  1681. begin
  1682. MatchingSymbol:=S; Found:=true; Break;
  1683. end;
  1684. end;
  1685. MatchedSymbol:=MatchedSymbol or Found;
  1686. MatchesAnySpecSymbol:=Found;
  1687. end;
  1688. function IsCommentPrefix: boolean;
  1689. begin
  1690. IsCommentPrefix:=MatchesAnySpecSymbol(SymbolConcat,ssCommentPrefix,pmLeft,false);
  1691. end;
  1692. function IsSingleLineCommentPrefix: boolean;
  1693. begin
  1694. IsSingleLineCommentPrefix:=MatchesAnySpecSymbol(SymbolConcat,ssCommentSingleLinePrefix,pmLeft,false);
  1695. end;
  1696. function IsCommentSuffix: boolean;
  1697. begin
  1698. IsCommentSuffix:=(MatchesAnySpecSymbol(SymbolConcat,ssCommentSuffix,pmRight,false))
  1699. and (CurrentCommentType=SymbolIndex);
  1700. end;
  1701. function IsStringPrefix: boolean;
  1702. begin
  1703. IsStringPrefix:=MatchesAnySpecSymbol(SymbolConcat,ssStringPrefix,pmLeft,false);
  1704. end;
  1705. function IsStringSuffix: boolean;
  1706. begin
  1707. IsStringSuffix:=MatchesAnySpecSymbol(SymbolConcat,ssStringSuffix,pmRight,false);
  1708. end;
  1709. function IsDirectivePrefix: boolean;
  1710. begin
  1711. IsDirectivePrefix:=MatchesAnySpecSymbol(SymbolConcat,ssDirectivePrefix,pmLeft,false);
  1712. end;
  1713. function IsDirectiveSuffix: boolean;
  1714. begin
  1715. IsDirectiveSuffix:=MatchesAnySpecSymbol(SymbolConcat,ssDirectiveSuffix,pmRight,false);
  1716. end;
  1717. function IsAsmPrefix(const WordS: string): boolean;
  1718. begin
  1719. IsAsmPrefix:=MatchesAnySpecSymbol(WordS,ssAsmPrefix,pmNone,true);
  1720. end;
  1721. function IsAsmSuffix(const WordS: string): boolean;
  1722. begin
  1723. IsAsmSuffix:=MatchesAnySpecSymbol(WordS,ssAsmSuffix,pmNone,true);
  1724. end;
  1725. function GetCharClass(C: char): TCharClass;
  1726. var CC: TCharClass;
  1727. begin
  1728. if C in WhiteSpaceChars then CC:=ccWhiteSpace else
  1729. if C in TabChars then CC:=ccTab else
  1730. if C in HashChars then CC:=ccHash else
  1731. if C in AlphaChars then CC:=ccAlpha else
  1732. if C in NumberChars then CC:=ccNumber else
  1733. if (LastCC=ccNumber) and (C in RealNumberChars) then
  1734. begin
  1735. if (C='.') then
  1736. begin
  1737. if (LineText[X+1]='.') then
  1738. cc:=ccSymbol
  1739. else
  1740. CC:=ccRealNumber
  1741. end
  1742. else
  1743. cc:=ccrealnumber;
  1744. end else
  1745. CC:=ccSymbol;
  1746. GetCharClass:=CC;
  1747. end;
  1748. procedure FormatWord(SClass: TCharClass; StartX:Sw_integer;EndX: Sw_integer);
  1749. var
  1750. C: byte;
  1751. WordS: string;
  1752. begin
  1753. C:=0;
  1754. WordS:=copy(LineText,StartX,EndX-StartX+1);
  1755. if IsAsmSuffix(WordS) and (InAsm=true) and (InComment=false) and
  1756. (InString=false) and (InDirective=false) then InAsm:=false;
  1757. if InDirective then C:=coDirectiveColor else
  1758. if InComment then C:=coCommentColor else
  1759. if InString then C:=coStringColor else
  1760. if InAsm then C:=coAssemblerColor else
  1761. case SClass of
  1762. ccWhiteSpace : C:=coWhiteSpaceColor;
  1763. ccTab : C:=coTabColor;
  1764. ccNumber :
  1765. if copy(WordS,1,1)='$' then
  1766. C:=coHexNumberColor
  1767. else
  1768. C:=coNumberColor;
  1769. ccHash :
  1770. C:=coStringColor;
  1771. ccSymbol :
  1772. C:=coSymbolColor;
  1773. ccAlpha :
  1774. begin
  1775. if Editor^.IsReservedWord(WordS) then
  1776. C:=coReservedWordColor
  1777. else
  1778. C:=coIdentifierColor;
  1779. end;
  1780. end;
  1781. if EndX+1>=StartX then
  1782. FillChar(Format[StartX],EndX+1-StartX,C);
  1783. if IsAsmPrefix(WordS) and (InString=false) and
  1784. (InAsm=false) and (InComment=false) and (InDirective=false) then
  1785. InAsm:=true;
  1786. end;
  1787. procedure ProcessChar(C: char);
  1788. var CC: TCharClass;
  1789. EX: Sw_integer;
  1790. begin
  1791. CC:=GetCharClass(C);
  1792. if ClassStart=X then
  1793. FirstCC:=CC;
  1794. if ( (CC<>LastCC) and
  1795. (
  1796. ((FirstCC=ccNumber) and (CC<>ccRealNumber)) or
  1797. (((CC<>ccAlpha) or (LastCC<>ccNumber) ) and
  1798. ( (CC<>ccNumber) or (LastCC<>ccAlpha) ) and
  1799. ( (CC<>ccNumber) or (LastCC<>ccHash) ) and
  1800. ( (CC<>ccRealNumber) or (LastCC<>ccNumber))
  1801. ))) or
  1802. (X>length(LineText)) or (CC=ccSymbol) then
  1803. begin
  1804. MatchedSymbol:=false;
  1805. EX:=X-1;
  1806. if (CC=ccSymbol) then
  1807. begin
  1808. if length(SymbolConcat)>=High(SymbolConcat) then
  1809. Delete(SymbolConcat,1,1);
  1810. SymbolConcat:=SymbolConcat+C;
  1811. end;
  1812. case CC of
  1813. ccSymbol :
  1814. if IsCommentSuffix and (InComment) then
  1815. Inc(EX) else
  1816. if IsStringSuffix and (InString) then
  1817. Inc(EX) else
  1818. if IsDirectiveSuffix and (InDirective) then
  1819. Inc(EX);
  1820. end;
  1821. if (C='$') and (MatchedSymbol=false) and (IsDirectivePrefix=false) then
  1822. CC:=ccNumber;
  1823. if CC<>ccSymbol then SymbolConcat:='';
  1824. FormatWord(LastCC,ClassStart,EX);
  1825. ClassStart:=EX+1;
  1826. case CC of
  1827. ccAlpha : ;
  1828. ccNumber :
  1829. if (LastCC<>ccAlpha) then;
  1830. ccSymbol :
  1831. if IsDirectivePrefix and (InComment=true) and (CurrentCommentType=1) and
  1832. (InDirective=false) then
  1833. begin InDirective:=true; InComment:=false; Dec(ClassStart,length(MatchingSymbol)-1); end else
  1834. if IsDirectiveSuffix and (InComment=false) and (InDirective=true) then
  1835. InDirective:=false else
  1836. if IsCommentPrefix and (InComment=false) and (InString=false) then
  1837. begin
  1838. InComment:=true;
  1839. CurrentCommentType:=SymbolIndex;
  1840. InSingleLineComment:=IsSingleLineCommentPrefix;
  1841. {InString:=false; }
  1842. Dec(ClassStart,length(MatchingSymbol)-1);
  1843. end
  1844. else
  1845. if IsCommentSuffix and (InComment) then
  1846. begin InComment:=false; InString:=false; end else
  1847. if IsStringPrefix and (InComment=false) and (InString=false) then
  1848. begin InString:=true; Dec(ClassStart,length(MatchingSymbol)-1); end else
  1849. if IsStringSuffix and (InComment=false) and (InString=true) then
  1850. InString:=false;
  1851. end;
  1852. if MatchedSymbol and (InComment=false) then
  1853. SymbolConcat:='';
  1854. LastCC:=CC;
  1855. end;
  1856. end;
  1857. var CurLine: Sw_integer;
  1858. Line,NextLine,PrevLine{,OldLine}: PCustomLine;
  1859. PrevLI,LI,NextLI: PEditorLineInfo;
  1860. begin
  1861. if (not Editor^.IsFlagSet(efSyntaxHighlight)) or (FromLine>=GetLineCount) then
  1862. begin
  1863. SetLineFormat(Editor,FromLine,'');
  1864. DoUpdateAttrs:=GetLineCount;
  1865. {$ifdef TEST_PARTIAL_SYNTAX}
  1866. LastSyntaxedLine:=GetLineCount;
  1867. if not SyntaxComplete then
  1868. begin
  1869. SyntaxComplete:=true;
  1870. DoSyntaxStateChanged;
  1871. end;
  1872. (* { no Idle necessary }
  1873. EventMask:=EventMask and not evIdle;*)
  1874. {$endif TEST_PARTIAL_SYNTAX}
  1875. Editor^.SyntaxStateChanged;
  1876. Exit;
  1877. end;
  1878. {$ifdef TEST_PARTIAL_SYNTAX}
  1879. If Editor^.IsFlagSet(efSyntaxHighlight) and (LastSyntaxedLine<FromLine)
  1880. and (FromLine<GetLineCount) then
  1881. CurLine:=LastSyntaxedLine
  1882. else
  1883. {$endif TEST_PARTIAL_SYNTAX}
  1884. CurLine:=FromLine;
  1885. if CurLine>0 then
  1886. PrevLine:=GetLine(CurLine-1)
  1887. else
  1888. PrevLine:=nil;
  1889. repeat
  1890. Line:=GetLine(CurLine);
  1891. if Assigned(PrevLine) then PrevLI:=PrevLine^.GetEditorInfo(Editor) else PrevLI:=nil;
  1892. if Assigned(Line) then LI:=Line^.GetEditorInfo(Editor) else LI:=nil;
  1893. InSingleLineComment:=false;
  1894. if PrevLI<>nil then
  1895. begin
  1896. InAsm:=PrevLI^.EndsWithAsm;
  1897. InComment:=PrevLI^.EndsWithComment and not PrevLI^.EndsInSingleLineComment;
  1898. CurrentCommentType:=PrevLI^.EndCommentType;
  1899. InDirective:=PrevLI^.EndsWithDirective;
  1900. end
  1901. else
  1902. begin
  1903. InAsm:=false;
  1904. InComment:=false;
  1905. CurrentCommentType:=0;
  1906. InDirective:=false;
  1907. end;
  1908. { OldLine:=Line;}
  1909. LI^.BeginsWithAsm:=InAsm;
  1910. LI^.BeginsWithComment:=InComment;
  1911. LI^.BeginsWithDirective:=InDirective;
  1912. LI^.BeginCommentType:=CurrentCommentType;
  1913. LineText:=GetLineText(CurLine);
  1914. Format:=CharStr(chr(coTextColor),length(LineText));
  1915. LastCC:=ccWhiteSpace;
  1916. ClassStart:=1;
  1917. SymbolConcat:='';
  1918. InString:=false;
  1919. if LineText<>'' then
  1920. begin
  1921. for X:=1 to length(LineText) do
  1922. ProcessChar(LineText[X]);
  1923. Inc(X);
  1924. ProcessChar(' ');
  1925. end;
  1926. SetLineFormat(Editor,CurLine,Format);
  1927. LI^.EndsWithAsm:=InAsm;
  1928. LI^.EndsWithComment:=InComment;
  1929. LI^.EndsInSingleLineComment:=InSingleLineComment;
  1930. LI^.EndCommentType:=CurrentCommentType;
  1931. LI^.EndsWithDirective:=InDirective;
  1932. Inc(CurLine);
  1933. if CurLine>=GetLineCount then
  1934. Break;
  1935. NextLine:=GetLine(CurLine);
  1936. if Assigned(NextLine) then NextLI:=NextLine^.GetEditorInfo(Editor) else NextLI:=nil;
  1937. if ((Attrs and attrForceFull)=0) then
  1938. if (* Why should we go
  1939. (InAsm=false) and (NextLI^.BeginsWithAsm=false) and
  1940. (InComment=false) and (NextLI^.BeginsWithComment=false) and
  1941. (InDirective=false) and (NextLI^.BeginsWithDirective=false) and
  1942. { OldLine = Line so this is nonsense}
  1943. (PrevLI^.EndsWithComment=LI^.EndsWithComment) and
  1944. (PrevLI^.EndsWithAsm=LI^.EndsWithAsm) and
  1945. (PrevLI^.EndsWithDirective=LI^.EndsWithDirective) and *)
  1946. {$ifdef TEST_PARTIAL_SYNTAX}
  1947. (CurLine>FromLine) and
  1948. {$endif TEST_PARTIAL_SYNTAX}
  1949. (NextLI^.BeginsWithAsm=LI^.EndsWithAsm) and
  1950. (NextLI^.BeginsWithComment=LI^.EndsWithComment) and
  1951. (NextLI^.BeginsWithDirective=LI^.EndsWithDirective) and
  1952. (NextLI^.BeginCommentType=LI^.EndCommentType) and
  1953. (NextLI^.Format<>nil) then
  1954. Break;
  1955. {$ifdef TEST_PARTIAL_SYNTAX}
  1956. if (CurLine<GetLineCount) and
  1957. (CurLine>FromLine) and
  1958. ((Attrs and attrForceFull)=0) and
  1959. (CurLine>GetLastVisibleLine) then
  1960. begin
  1961. If SyntaxComplete then
  1962. begin
  1963. SyntaxComplete:=false;
  1964. DoSyntaxStateChanged;
  1965. end;
  1966. LastSyntaxedLine:=CurLine-1;
  1967. break;
  1968. end;
  1969. {$endif TEST_PARTIAL_SYNTAX}
  1970. PrevLine:=Line;
  1971. until false;
  1972. DoUpdateAttrs:=CurLine;
  1973. {$ifdef TEST_PARTIAL_SYNTAX}
  1974. If LastSyntaxedLine<CurLine-1 then
  1975. LastSyntaxedLine:=CurLine-1;
  1976. if CurLine=GetLineCount then
  1977. begin
  1978. SyntaxComplete:=true;
  1979. DoSyntaxStateChanged;
  1980. end;
  1981. {$endif TEST_PARTIAL_SYNTAX}
  1982. end;
  1983. function TCustomCodeEditorCore.DoUpdateAttrsRange(Editor: PCustomCodeEditor; FromLine, ToLine: sw_integer;
  1984. Attrs: byte): sw_integer;
  1985. var Line: Sw_integer;
  1986. begin
  1987. Lock(Editor);
  1988. Line:=FromLine;
  1989. repeat
  1990. Line:=DoUpdateAttrs(Editor,Line,Attrs);
  1991. until (Line>=GetLineCount) or (Line>ToLine);
  1992. DoUpdateAttrsRange:=Line;
  1993. Unlock(Editor);
  1994. end;
  1995. procedure TCustomCodeEditorCore.AddAction(AAction: byte; AStartPos, AEndPos: TPoint; AText: string);
  1996. begin
  1997. Abstract;
  1998. end;
  1999. procedure TCustomCodeEditorCore.AddGroupedAction(AAction : byte);
  2000. begin
  2001. Abstract;
  2002. end;
  2003. procedure TCustomCodeEditorCore.CloseGroupedAction(AAction : byte);
  2004. begin
  2005. Abstract;
  2006. end;
  2007. function TCustomCodeEditorCore.GetUndoActionCount: sw_integer;
  2008. begin
  2009. Abstract;
  2010. GetUndoActionCount:=0;
  2011. end;
  2012. function TCustomCodeEditorCore.GetRedoActionCount: sw_integer;
  2013. begin
  2014. Abstract;
  2015. GetRedoActionCount:=0;
  2016. end;
  2017. destructor TCustomCodeEditorCore.Done;
  2018. begin
  2019. {$ifdef DEBUG}
  2020. if Bindings^.Count>0 then
  2021. ErrorBox('Internal error: there are still '+IntToStr(Bindings^.Count)+' editors '+
  2022. 'registered at TCodeEditorCode.Done!!!',nil);
  2023. {$endif}
  2024. if Assigned(Bindings) then Dispose(Bindings, Done); Bindings:=nil;
  2025. inherited Done;
  2026. end;
  2027. procedure TCustomCodeEditor.Lock;
  2028. begin
  2029. Inc(LockFlag);
  2030. end;
  2031. procedure TCustomCodeEditor.UnLock;
  2032. begin
  2033. {$ifdef DEBUG}
  2034. if lockflag=0 then
  2035. Bug('negative lockflag',nil)
  2036. else
  2037. {$endif DEBUG}
  2038. Dec(LockFlag);
  2039. if (LockFlag>0) then
  2040. Exit;
  2041. if DrawCalled then
  2042. DrawView;
  2043. If DrawCursorCalled then
  2044. Begin
  2045. DrawCursor;
  2046. DrawCursorCalled:=false;
  2047. End;
  2048. end;
  2049. procedure TCustomCodeEditor.DrawIndicator;
  2050. begin
  2051. { Abstract }
  2052. end;
  2053. procedure TCustomCodeEditor.AdjustSelectionPos(CurPosX, CurPosY: sw_integer; DeltaX, DeltaY: sw_integer);
  2054. var CP: TPoint;
  2055. begin
  2056. if ValidBlock=false then Exit;
  2057. CP.X:=CurPosX; CP.Y:=CurPosY;
  2058. if (PosToOfsP(SelStart)<=PosToOfsP(CP)) and (PosToOfsP(CP)<PosToOfsP(SelEnd)) then
  2059. begin
  2060. { CurPos is IN selection }
  2061. Inc(SelEnd.Y,DeltaY);
  2062. if (CP.Y=SelEnd.Y) and
  2063. ((SelStart.Y<>SelEnd.Y) or (SelStart.X<=CP.X)) and
  2064. (CP.X<=SelEnd.X) then
  2065. Inc(SelEnd.X,DeltaX);
  2066. SelectionChanged;
  2067. end
  2068. else
  2069. if (PosToOfsP(CP)<=PosToOfsP(SelStart)) then
  2070. begin
  2071. { CurPos is BEFORE selection }
  2072. if (CP.Y=SelStart.Y) and (CP.Y=SelEnd.Y) and (DeltaY<0) then
  2073. begin
  2074. SelStart:=CurPos; SelEnd:=CurPos;
  2075. end
  2076. else
  2077. if (CP.Y=SelStart.Y) then
  2078. begin
  2079. if CP.X<SelStart.X then
  2080. Inc(SelStart.X,DeltaX);
  2081. end;
  2082. { else}
  2083. begin
  2084. Inc(SelStart.Y,DeltaY);
  2085. Inc(SelEnd.Y,DeltaY);
  2086. end;
  2087. if SelEnd.Y=CurPos.Y then Inc(SelEnd.X,DeltaX);
  2088. SelectionChanged;
  2089. end
  2090. else
  2091. begin
  2092. { CurPos is AFTER selection }
  2093. { actually we don't have to do anything here }
  2094. end;
  2095. end;
  2096. function TCustomCodeEditor.GetFlags: longint;
  2097. begin
  2098. { Abstract }
  2099. GetFlags:=0;
  2100. end;
  2101. procedure TCustomCodeEditor.SetFlags(AFlags: longint);
  2102. begin
  2103. { Abstract }
  2104. end;
  2105. function TCustomCodeEditor.GetModified: boolean;
  2106. begin
  2107. { Abstract }
  2108. GetModified:=true;
  2109. end;
  2110. procedure TCustomCodeEditor.SetModified(AModified: boolean);
  2111. begin
  2112. { Abstract }
  2113. end;
  2114. function TCustomCodeEditor.GetStoreUndo: boolean;
  2115. begin
  2116. { Abstract }
  2117. GetStoreUndo:=false;
  2118. end;
  2119. procedure TCustomCodeEditor.SetStoreUndo(AStore: boolean);
  2120. begin
  2121. { Abstract }
  2122. end;
  2123. function TCustomCodeEditor.GetSyntaxCompleted: boolean;
  2124. begin
  2125. { Abstract }
  2126. GetSyntaxCompleted:=true;
  2127. end;
  2128. procedure TCustomCodeEditor.SetSyntaxCompleted(SC : boolean);
  2129. begin
  2130. { Abstract }
  2131. end;
  2132. function TCustomCodeEditor.GetLastSyntaxedLine: sw_integer;
  2133. begin
  2134. Abstract;
  2135. GetLastSyntaxedLine:=0;
  2136. end;
  2137. procedure TCustomCodeEditor.SetLastSyntaxedLine(ALine: sw_integer);
  2138. begin
  2139. Abstract;
  2140. end;
  2141. function TCustomCodeEditor.IsFlagSet(AFlag: longint): boolean;
  2142. begin
  2143. IsFlagSet:=(GetFlags and AFlag)=AFlag;
  2144. end;
  2145. function TCustomCodeEditor.GetTabSize: integer;
  2146. begin
  2147. { Abstract }
  2148. GetTabSize:=5;
  2149. end;
  2150. procedure TCustomCodeEditor.SetTabSize(ATabSize: integer);
  2151. begin
  2152. { Abstract }
  2153. end;
  2154. function TCustomCodeEditor.IsReadOnly: boolean;
  2155. begin
  2156. { Abstract }
  2157. IsReadOnly:=false;
  2158. end;
  2159. function TCustomCodeEditor.IsClipboard: Boolean;
  2160. begin
  2161. { Abstract }
  2162. IsClipboard:=false;
  2163. end;
  2164. function TCustomCodeEditor.GetLineCount: sw_integer;
  2165. begin
  2166. Abstract;
  2167. GetLineCount:=0;
  2168. end;
  2169. function TCustomCodeEditor.GetLine(LineNo: sw_integer): PCustomLine;
  2170. begin
  2171. Abstract;
  2172. GetLine:=nil;
  2173. end;
  2174. function TCustomCodeEditor.CharIdxToLinePos(Line,CharIdx: sw_integer): sw_integer;
  2175. begin
  2176. Abstract;
  2177. CharIdxToLinePos:=0;
  2178. end;
  2179. function TCustomCodeEditor.LinePosToCharIdx(Line,X: sw_integer): sw_integer;
  2180. begin
  2181. Abstract;
  2182. LinePosToCharIdx:=0;
  2183. end;
  2184. function TCustomCodeEditor.GetLineText(I: sw_integer): string;
  2185. begin
  2186. Abstract;
  2187. GetLineText:='';
  2188. end;
  2189. procedure TCustomCodeEditor.SetDisplayText(I: sw_integer;const S: string);
  2190. begin
  2191. Abstract;
  2192. end;
  2193. function TCustomCodeEditor.GetDisplayText(I: sw_integer): string;
  2194. begin
  2195. Abstract;
  2196. GetDisplayText:='';
  2197. end;
  2198. procedure TCustomCodeEditor.SetLineText(I: sw_integer;const S: string);
  2199. begin
  2200. Abstract;
  2201. end;
  2202. procedure TCustomCodeEditor.GetDisplayTextFormat(I: sw_integer;var DT,DF:string);
  2203. begin
  2204. Abstract;
  2205. end;
  2206. function TCustomCodeEditor.GetLineFormat(I: sw_integer): string;
  2207. begin
  2208. { Abstract }
  2209. GetLineFormat:='';
  2210. end;
  2211. procedure TCustomCodeEditor.SetLineFormat(I: sw_integer;const S: string);
  2212. begin
  2213. { Abstract }
  2214. end;
  2215. procedure TCustomCodeEditor.DeleteAllLines;
  2216. begin
  2217. Abstract;
  2218. end;
  2219. procedure TCustomCodeEditor.DeleteLine(I: sw_integer);
  2220. begin
  2221. Abstract;
  2222. end;
  2223. procedure TCustomCodeEditor.InsertLine(LineNo: sw_integer; const S: string);
  2224. begin
  2225. Abstract;
  2226. end;
  2227. procedure TCustomCodeEditor.AddLine(const S: string);
  2228. begin
  2229. Abstract;
  2230. end;
  2231. function TCustomCodeEditor.GetErrorMessage: string;
  2232. begin
  2233. Abstract;
  2234. GetErrorMessage:='';
  2235. end;
  2236. procedure TCustomCodeEditor.SetErrorMessage(const S: string);
  2237. begin
  2238. Abstract;
  2239. end;
  2240. procedure TCustomCodeEditor.GetContent(ALines: PUnsortedStringCollection);
  2241. begin
  2242. Abstract;
  2243. end;
  2244. procedure TCustomCodeEditor.SetContent(ALines: PUnsortedStringCollection);
  2245. begin
  2246. Abstract;
  2247. end;
  2248. function TCustomCodeEditor.LoadFromStream(Stream: PStream): boolean;
  2249. begin
  2250. Abstract;
  2251. LoadFromStream:=false;
  2252. end;
  2253. function TCustomCodeEditor.SaveToStream(Stream: PStream): boolean;
  2254. var A,B: TPoint;
  2255. begin
  2256. A.Y:=0; A.X:=0;
  2257. B.Y:=GetLineCount-1;
  2258. if GetLineCount>0 then
  2259. B.X:=length(GetDisplayText(B.Y))
  2260. else
  2261. B.X:=0;
  2262. SaveToStream:=SaveAreaToStream(Stream,A,B);
  2263. end;
  2264. function TCustomCodeEditor.SaveAreaToStream(Stream: PStream; StartP,EndP: TPoint): boolean;
  2265. begin
  2266. Abstract;
  2267. SaveAreaToStream:=false;
  2268. end;
  2269. function TCustomCodeEditor.LoadFromFile(const AFileName: string): boolean;
  2270. var S: PBufStream;
  2271. OK: boolean;
  2272. begin
  2273. New(S, Init(AFileName,stOpenRead,EditorTextBufSize));
  2274. OK:=Assigned(S);
  2275. {$ifdef TEST_PARTIAL_SYNTAX}
  2276. SetSyntaxCompleted(false);
  2277. { Idle necessary }
  2278. EventMask:=EventMask or evIdle;
  2279. {$endif TEST_PARTIAL_SYNTAX}
  2280. if OK then OK:=LoadFromStream(S);
  2281. if Assigned(S) then Dispose(S, Done);
  2282. LoadFromFile:=OK;
  2283. end;
  2284. function TCustomCodeEditor.SaveToFile(const AFileName: string): boolean;
  2285. var OK: boolean;
  2286. S: PBufStream;
  2287. begin
  2288. New(S, Init(AFileName,stCreate,EditorTextBufSize));
  2289. OK:=Assigned(S) and (S^.Status=stOK);
  2290. if OK then OK:=SaveToStream(S);
  2291. if Assigned(S) then Dispose(S, Done);
  2292. SaveToFile:=OK;
  2293. end;
  2294. function TCustomCodeEditor.InsertFrom(Editor: PCustomCodeEditor): Boolean;
  2295. var OK: boolean;
  2296. LineDelta,LineCount: Sw_integer;
  2297. StartPos,DestPos,BPos,EPos: TPoint;
  2298. LineStartX,LineEndX: Sw_integer;
  2299. S,OrigS,AfterS: string;
  2300. VerticalBlock: boolean;
  2301. SEnd: TPoint;
  2302. begin
  2303. if Editor^.IsFlagSet(efVerticalBlocks) then
  2304. begin
  2305. NotImplemented;
  2306. Exit;
  2307. end;
  2308. Lock;
  2309. { every data in the clipboard gets a new line }
  2310. if (Clipboard=@Self) and (CurPos.X>0) then
  2311. InsertNewLine;
  2312. OK:=(Editor^.SelStart.X<>Editor^.SelEnd.X) or (Editor^.SelStart.Y<>Editor^.SelEnd.Y);
  2313. if OK then
  2314. begin
  2315. StartPos:=CurPos; DestPos:=CurPos;
  2316. EPos:=CurPos;
  2317. VerticalBlock:=Editor^.IsFlagSet(efVerticalBlocks);
  2318. LineDelta:=0; LineCount:=(Editor^.SelEnd.Y-Editor^.SelStart.Y)+1;
  2319. OK:=GetLineCount<MaxLineCount;
  2320. OrigS:=GetDisplayText(DestPos.Y);
  2321. AfterS:=Copy(OrigS,DestPos.X+1,High(OrigS));
  2322. while OK and (LineDelta<LineCount) do
  2323. begin
  2324. if (LineDelta>0) and (VerticalBlock=false) then
  2325. begin
  2326. InsertLine(DestPos.Y,'');
  2327. BPos.X:=0;BPos.Y:=DestPos.Y;
  2328. EPOS.X:=0;EPos.Y:=DestPos.Y;
  2329. AddAction(eaInsertLine,BPos,EPos,'');
  2330. LimitsChanged;
  2331. end;
  2332. if (LineDelta=0) or VerticalBlock then
  2333. LineStartX:=Editor^.SelStart.X
  2334. else
  2335. LineStartX:=0;
  2336. if (LineDelta=LineCount-1) or VerticalBlock then
  2337. LineEndX:=Editor^.SelEnd.X-1
  2338. else
  2339. LineEndX:=High(S);
  2340. if LineEndX<LineStartX then
  2341. S:=''
  2342. else if VerticalBlock then
  2343. S:=RExpand(copy(Editor^.GetLineText(Editor^.SelStart.Y+LineDelta),LineStartX+1,LineEndX-LineStartX+1),
  2344. Min(LineEndX-LineStartX+1,High(S)))
  2345. else
  2346. S:=copy(Editor^.GetLineText(Editor^.SelStart.Y+LineDelta),LineStartX+1,LineEndX-LineStartX+1);
  2347. if VerticalBlock=false then
  2348. begin
  2349. If LineDelta>0 then
  2350. OrigS:='';
  2351. if LineDelta=LineCount-1 then
  2352. begin
  2353. SetLineText(DestPos.Y,RExpand(copy(OrigS,1,DestPos.X),DestPos.X)+S+AfterS);
  2354. BPos.X:=DestPos.X;BPos.Y:=DestPos.Y;
  2355. EPOS.X:=DestPos.X+Length(S);EPos.Y:=DestPos.Y;
  2356. AddAction(eaInsertText,BPos,EPos,S);
  2357. end
  2358. else
  2359. begin
  2360. SetLineText(DestPos.Y,RExpand(copy(OrigS,1,DestPos.X),DestPos.X)+S);
  2361. BPos.X:=DestPos.X;BPos.Y:=DestPos.Y;
  2362. EPOS.X:=DestPos.X+Length(S);EPos.Y:=DestPos.Y;
  2363. AddAction(eaInsertText,BPos,EPos,S);
  2364. end;
  2365. if LineDelta=LineCount-1 then
  2366. begin
  2367. SEnd.Y:=DestPos.Y;
  2368. SEnd.X:=DestPos.X+length(S);
  2369. end
  2370. else
  2371. begin
  2372. Inc(DestPos.Y);
  2373. DestPos.X:=0;
  2374. end;
  2375. end
  2376. else { if VerticalBlock=false then .. else }
  2377. begin
  2378. { this is not yet implemented !! PM }
  2379. S:=RExpand(S,LineEndX-LineStartX+1);
  2380. end;
  2381. Inc(LineDelta);
  2382. OK:=GetLineCount<MaxLineCount;
  2383. end;
  2384. if OK=false then EditorDialog(edTooManyLines,nil);
  2385. { mainly to force eaMove insertion }
  2386. if not IsClipboard then
  2387. SetCurPtr(EPos.X,EPos.Y);
  2388. SetCurPtr(StartPos.X,StartPos.Y);
  2389. UpdateAttrs(StartPos.Y,attrAll);
  2390. SetModified(true);
  2391. LimitsChanged;
  2392. SetSelection(CurPos,SEnd);
  2393. if IsClipboard then
  2394. begin
  2395. Inc(DestPos.X,length(S));
  2396. SetCurPtr(DestPos.X,DestPos.Y);
  2397. end;
  2398. DrawView;
  2399. end;
  2400. UnLock;
  2401. InsertFrom:=OK;
  2402. end;
  2403. function TCustomCodeEditor.InsertText(const S: string): Boolean;
  2404. var I: sw_integer;
  2405. OldPos: TPoint;
  2406. HoldUndo : boolean;
  2407. begin
  2408. Lock;
  2409. OldPos:=CurPos;
  2410. HoldUndo:=GetStoreUndo;
  2411. SetStoreUndo(false);
  2412. for I:=1 to length(S) do
  2413. AddChar(S[I]);
  2414. InsertText:=true;
  2415. SetStoreUndo(HoldUndo);
  2416. AddAction(eaInsertText,OldPos,CurPos,S);
  2417. UnLock;
  2418. end;
  2419. procedure TCustomCodeEditor.ModifiedChanged;
  2420. begin
  2421. { Abstract }
  2422. end;
  2423. procedure TCustomCodeEditor.PositionChanged;
  2424. begin
  2425. { Abstract }
  2426. end;
  2427. procedure TCustomCodeEditor.TabSizeChanged;
  2428. begin
  2429. { Abstract }
  2430. end;
  2431. procedure TCustomCodeEditor.SyntaxStateChanged;
  2432. begin
  2433. { Abstract }
  2434. end;
  2435. procedure TCustomCodeEditor.StoreUndoChanged;
  2436. begin
  2437. { Abstract }
  2438. end;
  2439. function TCustomCodeEditor.GetSpecSymbolCount(SpecClass: TSpecSymbolClass): integer;
  2440. begin
  2441. { Abstract }
  2442. GetSpecSymbolCount:=0;
  2443. end;
  2444. function TCustomCodeEditor.GetSpecSymbol(SpecClass: TSpecSymbolClass; Index: integer): string;
  2445. begin
  2446. Abstract;
  2447. GetSpecSymbol:='';
  2448. end;
  2449. function TCustomCodeEditor.IsReservedWord(const S: string): boolean;
  2450. begin
  2451. { Abstract }
  2452. IsReservedWord:=false;
  2453. end;
  2454. function TCustomCodeEditor.TranslateCodeTemplate(const Shortcut: string; ALines: PUnsortedStringCollection): boolean;
  2455. begin
  2456. { Abstract }
  2457. TranslateCodeTemplate:=false;
  2458. end;
  2459. function TCustomCodeEditor.CompleteCodeWord(const WordS: string; var Text: string): boolean;
  2460. begin
  2461. { Abstract }
  2462. Text:='';
  2463. CompleteCodeWord:=false;
  2464. end;
  2465. function TCustomCodeEditor.GetCodeCompleteWord: string;
  2466. begin
  2467. { Abstract }
  2468. GetCodeCompleteWord:='';
  2469. end;
  2470. procedure TCustomCodeEditor.AdjustSelection(DeltaX, DeltaY: sw_integer);
  2471. begin
  2472. AdjustSelectionPos(CurPos.X,CurPos.Y,DeltaX,DeltaY);
  2473. end;
  2474. procedure TCustomCodeEditor.TrackCursor(Center: boolean);
  2475. var D: TPoint;
  2476. begin
  2477. D:=Delta;
  2478. if CurPos.Y<Delta.Y then D.Y:=CurPos.Y else
  2479. if CurPos.Y>Delta.Y+Size.Y-1 then D.Y:=CurPos.Y-Size.Y+1;
  2480. if CurPos.X<Delta.X then D.X:=CurPos.X else
  2481. if CurPos.X>Delta.X+Size.X-1 then D.X:=CurPos.X-Size.X+1;
  2482. if {((Delta.X<>D.X) or (Delta.Y<>D.Y)) and }Center then
  2483. begin
  2484. { loose centering for debugger PM }
  2485. while (CurPos.Y-D.Y)<(Size.Y div 3) do Dec(D.Y);
  2486. while (CurPos.Y-D.Y)>2*(Size.Y div 3) do Inc(D.Y);
  2487. end;
  2488. if (Delta.X<>D.X) or (Delta.Y<>D.Y) then
  2489. ScrollTo(D.X,D.Y);
  2490. DrawCursor;
  2491. end;
  2492. procedure TCustomCodeEditor.ScrollTo(X, Y: sw_Integer);
  2493. begin
  2494. inherited ScrollTo(X,Y);
  2495. if (HScrollBar=nil) or (VScrollBar=nil) then
  2496. begin Delta.X:=X; Delta.Y:=Y; end;
  2497. DrawView;
  2498. end;
  2499. function TCustomCodeEditor.IsModal: boolean;
  2500. var IsM: boolean;
  2501. begin
  2502. IsM:=GetState(sfModal);
  2503. if Assigned(Owner) then
  2504. IsM:=IsM or Owner^.GetState(sfModal);
  2505. IsModal:=IsM;
  2506. end;
  2507. procedure TCustomCodeEditor.FlagsChanged(OldFlags: longint);
  2508. var I: sw_integer;
  2509. begin
  2510. Lock;
  2511. if ((OldFlags xor GetFlags) and efCodeComplete)<>0 then
  2512. ClearCodeCompleteWord;
  2513. SetInsertMode(IsFlagSet(efInsertMode));
  2514. if IsFlagSet(efSyntaxHighlight) then
  2515. UpdateAttrs(0,attrAll) else
  2516. for I:=0 to GetLineCount-1 do
  2517. SetLineFormat(I,'');
  2518. DrawView;
  2519. UnLock;
  2520. end;
  2521. procedure TCustomCodeEditor.LimitsChanged;
  2522. begin
  2523. Abstract;
  2524. end;
  2525. procedure TCustomCodeEditor.DoLimitsChanged;
  2526. begin
  2527. SetLimit(MaxLineLength+1,GetLineCount);
  2528. end;
  2529. procedure TCustomCodeEditor.BindingsChanged;
  2530. begin
  2531. { Abstract }
  2532. end;
  2533. procedure TCustomCodeEditor.ContentsChanged;
  2534. begin
  2535. DrawView;
  2536. end;
  2537. procedure TCustomCodeEditor.ConvertEvent(var Event: TEvent);
  2538. var
  2539. Key: Word;
  2540. begin
  2541. if Event.What = evKeyDown then
  2542. begin
  2543. if (Event.KeyShift and kbShift <> 0) and
  2544. (Event.ScanCode >= $47) and (Event.ScanCode <= $51) then
  2545. Event.CharCode := #0;
  2546. Key := Event.KeyCode;
  2547. if KeyState <> 0 then
  2548. begin
  2549. if (Lo(Key) >= $01) and (Lo(Key) <= $1A) then Inc(Key, $40);
  2550. if (Lo(Key) >= $61) and (Lo(Key) <= $7A) then Dec(Key, $20);
  2551. end;
  2552. Key := ScanKeyMap(KeyMap[KeyState], Key);
  2553. if (KeyState<>0) and (Key=0) then
  2554. ClearEvent(Event); { eat second key if unrecognized after ^Q or ^K }
  2555. KeyState := 0;
  2556. if Key <> 0 then
  2557. if Hi(Key) = $FF then
  2558. begin
  2559. KeyState := Lo(Key);
  2560. ClearEvent(Event);
  2561. end
  2562. else
  2563. begin
  2564. Event.What := evCommand;
  2565. Event.Command := Key;
  2566. end;
  2567. end;
  2568. end;
  2569. procedure TCustomCodeEditor.SetLineFlagState(LineNo: sw_integer; Flags: longint; ASet: boolean);
  2570. var L: PCustomLine;
  2571. begin
  2572. L:=GetLine(LineNo);
  2573. if Assigned(L) then
  2574. with L^ do
  2575. if ASet then
  2576. SetFlags(GetFlags or Flags)
  2577. else
  2578. SetFlags(GetFlags and not Flags);
  2579. end;
  2580. procedure TCustomCodeEditor.SetLineFlagExclusive(Flags: longint; LineNo: sw_integer);
  2581. var I,Count: sw_integer;
  2582. L: PCustomLine;
  2583. begin
  2584. Lock;
  2585. Count:=GetLineCount;
  2586. for I:=0 to Count-1 do
  2587. begin
  2588. L:=GetLine(I);
  2589. if I=LineNo then
  2590. L^.SetFlags(L^.GetFlags or Flags)
  2591. else
  2592. L^.SetFlags(L^.GetFlags and (not Flags));
  2593. end;
  2594. UnLock;
  2595. end;
  2596. procedure TCustomCodeEditor.HandleEvent(var Event: TEvent);
  2597. var DontClear : boolean;
  2598. procedure CheckScrollBar(P: PScrollBar; var D: Sw_Integer);
  2599. begin
  2600. if (Event.InfoPtr = P) and (P^.Value <> D) then
  2601. begin
  2602. D := P^.Value;
  2603. DrawView;
  2604. end;
  2605. end;
  2606. procedure GetMousePos(var P: TPoint);
  2607. begin
  2608. MakeLocal(Event.Where,P);
  2609. Inc(P.X,Delta.X); Inc(P.Y,Delta.Y);
  2610. end;
  2611. type TCCAction = (ccCheck,ccClear,ccDontCare);
  2612. var
  2613. StartP,P: TPoint;
  2614. E: TEvent;
  2615. OldEvent : PEvent;
  2616. CCAction: TCCAction;
  2617. begin
  2618. CCAction:=ccClear;
  2619. E:=Event;
  2620. OldEvent:=CurEvent;
  2621. if (E.What and (evMouse or evKeyboard))<>0 then
  2622. CurEvent:=@E;
  2623. if (InASCIIMode=false) or (Event.What<>evKeyDown) then
  2624. if (Event.What<>evKeyDown) or (Event.KeyCode<>kbEnter) or (IsReadOnly=false) then
  2625. if (Event.What<>evKeyDown) or
  2626. ((Event.KeyCode<>kbEnter) and (Event.KeyCode<>kbEsc)) or
  2627. (GetCompleteState<>csOffering) then
  2628. ConvertEvent(Event);
  2629. case Event.What of
  2630. evMouseDown :
  2631. if MouseInView(Event.Where) then
  2632. if (Event.Buttons=mbRightButton) then
  2633. begin
  2634. MakeLocal(Event.Where,P); Inc(P.X); Inc(P.Y);
  2635. LocalMenu(P);
  2636. ClearEvent(Event);
  2637. end else
  2638. if Event.Buttons=mbLeftButton then
  2639. begin
  2640. GetMousePos(P);
  2641. StartP:=P;
  2642. SetCurPtr(P.X,P.Y);
  2643. repeat
  2644. GetMousePos(P);
  2645. if PointOfs(P)<PointOfs(StartP)
  2646. then SetSelection(P,StartP)
  2647. else SetSelection(StartP,P);
  2648. SetCurPtr(P.X,P.Y);
  2649. DrawView;
  2650. until not MouseEvent(Event, evMouseMove+evMouseAuto);
  2651. DrawView;
  2652. end;
  2653. evKeyDown :
  2654. begin
  2655. { Scancode is almost never zero PM }
  2656. { this is supposed to enable entering of ASCII chars below 32,
  2657. which are normally interpreted as control chars. So, when you enter
  2658. Alt+24 (on the numeric pad) then this will normally move the cursor
  2659. one line down, but if you do it in ASCII mode (also after Ctrl+B)
  2660. then this will insert the ASCII #24 char (upper arrow) in the
  2661. source code. - Gabor }
  2662. if InASCIIMode {and (Event.CharCode<>0)} then
  2663. begin
  2664. AddChar(Event.CharCode);
  2665. if (GetCompleteState<>csDenied) or (Event.CharCode=#32) then
  2666. CCAction:=ccCheck
  2667. else
  2668. CCAction:=ccClear;
  2669. end
  2670. else
  2671. begin
  2672. DontClear:=false;
  2673. case Event.KeyCode of
  2674. kbAltF10 :
  2675. Message(@Self,evCommand,cmLocalMenu,@Self);
  2676. kbEnter :
  2677. if IsReadOnly then
  2678. DontClear:=true else
  2679. if GetCompleteState=csOffering then
  2680. CodeCompleteApply
  2681. else
  2682. Message(@Self,evCommand,cmNewLine,nil);
  2683. kbEsc :
  2684. if GetCompleteState=csOffering then
  2685. CodeCompleteCancel else
  2686. if IsModal then
  2687. DontClear:=true;
  2688. else
  2689. case Event.CharCode of
  2690. #9,#32..#255 :
  2691. if (Event.CharCode=#9) and IsModal then
  2692. DontClear:=true
  2693. else
  2694. begin
  2695. NoSelect:=true;
  2696. AddChar(Event.CharCode);
  2697. NoSelect:=false;
  2698. if (GetCompleteState<>csDenied) or (Event.CharCode=#32) then
  2699. CCAction:=ccCheck
  2700. else
  2701. CCAction:=ccClear;
  2702. end;
  2703. else
  2704. DontClear:=true;
  2705. end; { case Event.CharCode .. }
  2706. end; { case Event.KeyCode .. }
  2707. if not DontClear then
  2708. ClearEvent(Event);
  2709. end;
  2710. InASCIIMode:=false;
  2711. end;
  2712. evCommand :
  2713. begin
  2714. DontClear:=false;
  2715. case Event.Command of
  2716. cmASCIIChar : InASCIIMode:=not InASCIIMode;
  2717. cmAddChar : AddChar(chr(longint(Event.InfoPtr)));
  2718. cmCharLeft : CharLeft;
  2719. cmCharRight : CharRight;
  2720. cmWordLeft : WordLeft;
  2721. cmWordRight : WordRight;
  2722. cmLineStart : LineStart;
  2723. cmLineEnd : LineEnd;
  2724. cmLineUp : LineUp;
  2725. cmLineDown : LineDown;
  2726. cmPageUp : PageUp;
  2727. cmPageDown : PageDown;
  2728. cmTextStart : TextStart;
  2729. cmTextEnd : TextEnd;
  2730. cmWindowStart : WindowStart;
  2731. cmWindowEnd : WindowEnd;
  2732. cmNewLine : begin
  2733. InsertNewLine;
  2734. TrackCursor(false);
  2735. end;
  2736. cmBreakLine : BreakLine;
  2737. cmBackSpace : BackSpace;
  2738. cmDelChar : DelChar;
  2739. cmDelWord : DelWord;
  2740. cmDelStart : DelStart;
  2741. cmDelEnd : DelEnd;
  2742. cmDelLine : DelLine;
  2743. cmInsMode : InsMode;
  2744. cmStartSelect : StartSelect;
  2745. cmHideSelect : HideSelect;
  2746. cmUpdateTitle : ;
  2747. cmEndSelect : EndSelect;
  2748. cmDelSelect : DelSelect;
  2749. cmCopyBlock : CopyBlock;
  2750. cmMoveBlock : MoveBlock;
  2751. cmIndentBlock : IndentBlock;
  2752. cmUnindentBlock : UnindentBlock;
  2753. cmSelStart : JumpSelStart;
  2754. cmSelEnd : JumpSelEnd;
  2755. cmLastCursorPos : JumpToLastCursorPos;
  2756. cmFindMatchingDelimiter : FindMatchingDelimiter(true);
  2757. cmFindMatchingDelimiterBack : FindMatchingDelimiter(false);
  2758. cmUpperCase : UpperCase;
  2759. cmLowerCase : LowerCase;
  2760. cmWordLowerCase : WordLowerCase;
  2761. cmWordUpperCase : WordUpperCase;
  2762. cmInsertOptions : InsertOptions;
  2763. cmToggleCase : ToggleCase;
  2764. cmJumpMark0..cmJumpMark9 : JumpMark(Event.Command-cmJumpMark0);
  2765. cmSetMark0..cmSetMark9 : DefineMark(Event.Command-cmSetMark0);
  2766. cmSelectWord : SelectWord;
  2767. cmSelectLine : SelectLine;
  2768. cmWriteBlock : WriteBlock;
  2769. cmReadBlock : ReadBlock;
  2770. cmPrintBlock : PrintBlock;
  2771. { ------ }
  2772. cmFind : Find;
  2773. cmReplace : Replace;
  2774. cmSearchAgain : DoSearchReplace;
  2775. cmJumpLine : GotoLine;
  2776. { ------ }
  2777. cmCut : ClipCut;
  2778. cmCopy : ClipCopy;
  2779. cmPaste : ClipPaste;
  2780. {$ifdef WinClipSupported}
  2781. cmCopyWin : ClipCopyWin;
  2782. cmPasteWin : ClipPasteWin;
  2783. {$endif WinClipSupported}
  2784. cmUndo : Undo;
  2785. cmRedo : Redo;
  2786. cmClear : DelSelect;
  2787. cmExpandCodeTemplate: ExpandCodeTemplate;
  2788. cmLocalMenu :
  2789. begin
  2790. P:=CurPos; Inc(P.X); Inc(P.Y);
  2791. LocalMenu(P);
  2792. end;
  2793. cmActivateMenu :
  2794. Message(Application,evCommand,cmMenu,nil);
  2795. else
  2796. begin
  2797. DontClear:=true;
  2798. CCAction:=ccDontCare;
  2799. end;
  2800. end;
  2801. if DontClear=false then
  2802. ClearEvent(Event);
  2803. end;
  2804. {$ifdef TEST_PARTIAL_SYNTAX}
  2805. evIdle :
  2806. begin
  2807. CCAction:=ccDontCare;
  2808. { Complete syntax by 20 lines increment }
  2809. { could already be quite lengthy on slow systems }
  2810. if not GetSyntaxCompleted then
  2811. UpdateAttrsRange(GetLastSyntaxedLine,GetLastSyntaxedLine+20,AttrAll);
  2812. end;
  2813. {$endif TEST_PARTIAL_SYNTAX}
  2814. evBroadcast :
  2815. begin
  2816. CCAction:=ccDontCare;
  2817. case Event.Command of
  2818. cmUpdate :
  2819. Update;
  2820. cmClearLineHighlights :
  2821. SetLineFlagExclusive(lfHighlightRow,-1);
  2822. cmResetDebuggerRow :
  2823. SetLineFlagExclusive(lfDebuggerRow,-1);
  2824. cmScrollBarChanged:
  2825. if (Event.InfoPtr = HScrollBar) or
  2826. (Event.InfoPtr = VScrollBar) then
  2827. begin
  2828. CheckScrollBar(HScrollBar, Delta.X);
  2829. CheckScrollBar(VScrollBar, Delta.Y);
  2830. end;
  2831. end;
  2832. end;
  2833. else CCAction:=ccDontCare;
  2834. end;
  2835. inherited HandleEvent(Event);
  2836. CurEvent:=OldEvent;
  2837. case CCAction of
  2838. ccCheck : CodeCompleteCheck;
  2839. ccClear : ClearCodeCompleteWord;
  2840. end;
  2841. end;
  2842. procedure TCustomCodeEditor.UpdateUndoRedo(cm : word; action : byte);
  2843. var UndoMenu : PMenuItem;
  2844. begin
  2845. UndoMenu:=PAdvancedMenuBar(MenuBar)^.GetMenuItem(cm);
  2846. if assigned(UndoMenu) then
  2847. begin
  2848. If assigned(UndoMenu^.Param) then
  2849. DisposeStr(UndoMenu^.Param);
  2850. if action<lastaction then
  2851. UndoMenu^.Param:=NewStr(ActionString[action]);
  2852. end;
  2853. end;
  2854. procedure TCustomCodeEditor.Update;
  2855. begin
  2856. Lock;
  2857. LimitsChanged;
  2858. SelectionChanged; HighlightChanged;
  2859. UnLock;
  2860. end;
  2861. function TCustomCodeEditor.GetLocalMenu: PMenu;
  2862. begin
  2863. GetLocalMenu:=nil;
  2864. end;
  2865. function TCustomCodeEditor.GetCommandTarget: PView;
  2866. begin
  2867. GetCommandTarget:=@Self;
  2868. end;
  2869. function TCustomCodeEditor.CreateLocalMenuView(var Bounds: TRect; M: PMenu): PMenuPopup;
  2870. var MV: PMenuPopup;
  2871. begin
  2872. New(MV, Init(Bounds, M));
  2873. CreateLocalMenuView:=MV;
  2874. end;
  2875. procedure TCustomCodeEditor.LocalMenu(P: TPoint);
  2876. var M: PMenu;
  2877. MV: PMenuPopUp;
  2878. R: TRect;
  2879. Re: word;
  2880. begin
  2881. M:=GetLocalMenu;
  2882. if M=nil then Exit;
  2883. if LastLocalCmd<>0 then
  2884. M^.Default:=SearchMenuItem(M,LastLocalCmd);
  2885. Desktop^.GetExtent(R);
  2886. MakeGlobal(P,R.A); {Desktop^.MakeLocal(R.A,R.A);}
  2887. MV:=CreateLocalMenuView(R,M);
  2888. Re:=Application^.ExecView(MV);
  2889. if M^.Default=nil then LastLocalCmd:=0
  2890. else LastLocalCmd:=M^.Default^.Command;
  2891. Dispose(MV, Done);
  2892. if Re<>0 then
  2893. Message(GetCommandTarget,evCommand,Re,@Self);
  2894. end;
  2895. procedure TCustomCodeEditor.Draw;
  2896. var SelectColor,
  2897. HighlightColColor,
  2898. HighlightRowColor,
  2899. ErrorMessageColor : word;
  2900. B: TDrawBuffer;
  2901. X,Y,AX,AY,MaxX: sw_integer;
  2902. PX: TPoint;
  2903. LineCount: sw_integer;
  2904. Line: PCustomLine;
  2905. LineText,Format: string;
  2906. isBreak : boolean;
  2907. C: char;
  2908. FreeFormat: array[0..MaxLineLength] of boolean;
  2909. Color: word;
  2910. ColorTab: array[coFirstColor..coLastColor] of word;
  2911. ErrorLine: integer;
  2912. ErrorMsg: string[MaxViewWidth];
  2913. function CombineColors(Orig,Modifier: byte): byte;
  2914. var Color: byte;
  2915. begin
  2916. if (Modifier and $0f)=0 then
  2917. Color:=(Orig and $0f) or (Modifier and $f0)
  2918. else
  2919. Color:=(Orig and $f0) or (Modifier and $0f);
  2920. { do not allow invisible }
  2921. { use white as foreground in this case }
  2922. if (Color and $f) = ((Color div $10) and $7) then
  2923. Color:=(Color and $F0) or $F;
  2924. CombineColors:=Color;
  2925. end;
  2926. begin
  2927. if LockFlag>0 then
  2928. begin
  2929. DrawCalled:=true;
  2930. Exit;
  2931. end;
  2932. DrawCalled:=false;
  2933. ErrorMsg:=copy(GetErrorMessage,1,MaxViewWidth);
  2934. if ErrorMsg='' then ErrorLine:=-1 else
  2935. if (CurPos.Y-Delta.Y)<(Size.Y div 2) then ErrorLine:=Size.Y-1
  2936. else ErrorLine:=0;
  2937. LineCount:=GetLineCount;
  2938. ColorTab[coTextColor]:=GetColor(1);
  2939. ColorTab[coWhiteSpaceColor]:=GetColor(2);
  2940. ColorTab[coCommentColor]:=GetColor(3);
  2941. ColorTab[coReservedWordColor]:=GetColor(4);
  2942. ColorTab[coIdentifierColor]:=GetColor(5);
  2943. ColorTab[coStringColor]:=GetColor(6);
  2944. ColorTab[coNumberColor]:=GetColor(7);
  2945. ColorTab[coAssemblerColor]:=GetColor(8);
  2946. ColorTab[coSymbolColor]:=GetColor(9);
  2947. ColorTab[coDirectiveColor]:=GetColor(13);
  2948. ColorTab[coHexNumberColor]:=GetColor(14);
  2949. ColorTab[coTabColor]:=GetColor(15);
  2950. { break same as error }
  2951. ColorTab[coBreakColor]:=GetColor(16);
  2952. SelectColor:=GetColor(10);
  2953. HighlightColColor:=GetColor(11);
  2954. HighlightRowColor:=GetColor(12);
  2955. ErrorMessageColor:=GetColor(16);
  2956. {$ifdef TEST_PARTIAL_SYNTAX}
  2957. If GetLastSyntaxedLine<Delta.Y+Size.Y then
  2958. UpdateAttrsRange(GetLastSyntaxedLine,Delta.Y+Size.Y,AttrAll);
  2959. {$endif TEST_PARTIAL_SYNTAX}
  2960. for Y:=0 to Size.Y-1 do
  2961. if Y=ErrorLine then
  2962. begin
  2963. MoveChar(B,' ',ErrorMessageColor,Size.X);
  2964. MoveStr(B,ErrorMsg,ErrorMessageColor);
  2965. WriteLine(0,Y,Size.X,1,B);
  2966. end else
  2967. begin
  2968. AY:=Delta.Y+Y;
  2969. Color:=ColorTab[coTextColor];
  2970. FillChar(FreeFormat,SizeOf(FreeFormat),1);
  2971. MoveChar(B,' ',Color,Size.X);
  2972. if AY<LineCount then
  2973. begin
  2974. Line:=GetLine(AY);
  2975. IsBreak:=GetLine(AY)^.IsFlagSet(lfBreakpoint);
  2976. end
  2977. else
  2978. begin
  2979. Line:=nil;
  2980. IsBreak:=false;
  2981. end;
  2982. GetDisplayTextFormat(AY,LineText,Format);
  2983. { if FlagSet(efSyntaxHighlight) then MaxX:=length(LineText)+1
  2984. else }MaxX:=Size.X+Delta.X;
  2985. for X:=1 to Min(MaxX,High(LineText)) do
  2986. begin
  2987. AX:=Delta.X+X-1;
  2988. if X<=length(LineText) then C:=LineText[X] else C:=' ';
  2989. PX.X:=AX-Delta.X; PX.Y:=AY;
  2990. if (Highlight.A.X<>Highlight.B.X) or (Highlight.A.Y<>Highlight.B.Y) then
  2991. begin
  2992. if (PointOfs(Highlight.A)<=PointOfs(PX)) and (PointOfs(PX)<PointOfs(Highlight.B)) then
  2993. begin
  2994. Color:=SelectColor;
  2995. FreeFormat[X]:=false;
  2996. end;
  2997. end else
  2998. { no highlight }
  2999. begin
  3000. if IsFlagSet(efVerticalBlocks) then
  3001. begin
  3002. if (SelStart.X<=AX) and (AX<=SelEnd.X) and
  3003. (SelStart.Y<=AY) and (AY<=SelEnd.Y) then
  3004. begin Color:=SelectColor; FreeFormat[X]:=false; end;
  3005. end else
  3006. if PointOfs(SelStart)<>PointOfs(SelEnd) then
  3007. if (PointOfs(SelStart)<=PointOfs(PX)) and (PointOfs(PX)<PointOfs(SelEnd)) then
  3008. begin Color:=SelectColor; FreeFormat[X]:=false; end;
  3009. end;
  3010. if FreeFormat[X] then
  3011. if X<=length(Format) then
  3012. {Color:=ColorTab[ord(Format[X])] else Color:=ColorTab[coTextColor];
  3013. this give BoundsCheckError with -Cr quite often PM }
  3014. Color:=ColorTab[ord(Format[X]) mod (coLastColor + 1)] else Color:=ColorTab[coTextColor];
  3015. if IsFlagSet(efHighlightRow) and
  3016. (PX.Y=CurPos.Y) then
  3017. begin
  3018. Color:=CombineColors(Color,HighlightRowColor);
  3019. FreeFormat[X]:=false;
  3020. end;
  3021. if IsFlagSet(efHighlightColumn) and (PX.X=CurPos.X) then
  3022. begin
  3023. Color:=CombineColors(Color,HighlightColColor);
  3024. FreeFormat[X]:=false;
  3025. end;
  3026. if Assigned(Line) and Line^.IsFlagSet(lfHighlightRow) then
  3027. begin
  3028. Color:=CombineColors(Color,HighlightRowColor);
  3029. FreeFormat[X]:=false;
  3030. end;
  3031. if isbreak then
  3032. begin
  3033. Color:=ColorTab[coBreakColor];
  3034. FreeFormat[X]:=false;
  3035. end;
  3036. if Assigned(Line) and Line^.isFlagSet(lfDebuggerRow) then
  3037. begin
  3038. Color:=CombineColors(Color,HighlightRowColor);
  3039. FreeFormat[X]:=false;
  3040. end;
  3041. if (0<=X-1-Delta.X) and (X-1-Delta.X<MaxViewWidth) then
  3042. MoveChar(B[X-1-Delta.X],C,Color,1);
  3043. end;
  3044. WriteLine(0,Y,Size.X,1,B);
  3045. end;
  3046. DrawCursor;
  3047. end;
  3048. procedure TCustomCodeEditor.DrawCursor;
  3049. begin
  3050. if lockflag>0 then
  3051. DrawCursorCalled:=true
  3052. else
  3053. SetCursor(CurPos.X-Delta.X,CurPos.Y-Delta.Y);
  3054. SetState(sfCursorIns,Overwrite);
  3055. end;
  3056. function TCustomCodeEditor.Overwrite: boolean;
  3057. begin
  3058. Overwrite:=not IsFlagSet(efInsertMode);
  3059. end;
  3060. procedure TCustomCodeEditor.SetCodeCompleteWord(const S: string);
  3061. begin
  3062. if S<>'' then
  3063. SetCompleteState(csOffering)
  3064. else
  3065. SetCompleteState(csInactive);
  3066. end;
  3067. procedure TCustomCodeEditor.ClearCodeCompleteWord;
  3068. begin
  3069. SetCodeCompleteWord('');
  3070. SetCompleteState(csInactive);
  3071. end;
  3072. function TCustomCodeEditor.GetCompleteState: TCompleteState;
  3073. begin
  3074. { Abstract }
  3075. GetCompleteState:=csInactive;
  3076. end;
  3077. procedure TCustomCodeEditor.SetCompleteState(AState: TCompleteState);
  3078. begin
  3079. { Abstract }
  3080. end;
  3081. function TCustomCodeEditor.UpdateAttrs(FromLine: sw_integer; Attrs: byte): sw_integer;
  3082. begin
  3083. Abstract;
  3084. UpdateAttrs:=-1;
  3085. end;
  3086. function TCustomCodeEditor.UpdateAttrsRange(FromLine, ToLine: sw_integer; Attrs: byte): sw_integer;
  3087. begin
  3088. Abstract;
  3089. UpdateAttrsRange:=-1;
  3090. end;
  3091. procedure TCustomCodeEditor.AddAction(AAction: byte; AStartPos, AEndPos: TPoint; AText: string);
  3092. begin
  3093. { Abstract }
  3094. end;
  3095. procedure TCustomCodeEditor.AddGroupedAction(AAction : byte);
  3096. begin
  3097. { Abstract }
  3098. end;
  3099. procedure TCustomCodeEditor.CloseGroupedAction(AAction : byte);
  3100. begin
  3101. { Abstract }
  3102. end;
  3103. function TCustomCodeEditor.GetUndoActionCount: sw_integer;
  3104. begin
  3105. { Abstract }
  3106. GetUndoActionCount:=0;
  3107. end;
  3108. function TCustomCodeEditor.GetRedoActionCount: sw_integer;
  3109. begin
  3110. { Abstract }
  3111. GetRedoActionCount:=0;
  3112. end;
  3113. procedure TCustomCodeEditor.Indent;
  3114. var S, PreS: string;
  3115. Shift: integer;
  3116. begin
  3117. S:=GetLineText(CurPos.Y);
  3118. if CurPos.Y>0 then
  3119. PreS:=RTrim(GetLineText(CurPos.Y-1),not IsFlagSet(efUseTabCharacters))
  3120. else
  3121. PreS:='';
  3122. if CurPos.X>=length(PreS) then
  3123. Shift:=GetTabSize
  3124. else
  3125. begin
  3126. Shift:=1;
  3127. while (CurPos.X+Shift<length(PreS)) and (PreS[CurPos.X+Shift]<>' ') do
  3128. Inc(Shift);
  3129. end;
  3130. SetLineText(CurPos.Y,RExpand(copy(S,1,CurPos.X+1),CurPos.X+1)+CharStr(' ',Shift)+copy(S,CurPos.X+2,High(S)));
  3131. SetCurPtr(CurPos.X+Shift,CurPos.Y);
  3132. UpdateAttrs(CurPos.Y,attrAll);
  3133. DrawLines(CurPos.Y);
  3134. SetModified(true);
  3135. end;
  3136. procedure TCustomCodeEditor.CharLeft;
  3137. begin
  3138. if CurPos.X=0 then Exit;
  3139. SetCurPtr(CurPos.X-1,CurPos.Y);
  3140. end;
  3141. procedure TCustomCodeEditor.CharRight;
  3142. begin
  3143. if CurPos.X>=MaxLineLength then
  3144. Exit;
  3145. SetCurPtr(CurPos.X+1,CurPos.Y);
  3146. end;
  3147. procedure TCustomCodeEditor.WordLeft;
  3148. var X, Y: sw_integer;
  3149. Line: string;
  3150. GotIt,FoundNonSeparator: boolean;
  3151. begin
  3152. X:=CurPos.X;
  3153. Y:=CurPos.Y;
  3154. GotIt:=false;
  3155. FoundNonSeparator:=false;
  3156. while (Y>=0) do
  3157. begin
  3158. if Y=CurPos.Y then
  3159. begin
  3160. X:=length(GetDisplayText(Y));
  3161. if CurPos.X<X then
  3162. X:=CurPos.X; Dec(X);
  3163. if (X=-1) then
  3164. begin
  3165. Dec(Y);
  3166. if Y>=0 then
  3167. X:=length(GetDisplayText(Y));
  3168. Break;
  3169. end;
  3170. end
  3171. else
  3172. X:=length(GetDisplayText(Y))-1;
  3173. Line:=GetDisplayText(Y);
  3174. while (X>=0) and (GotIt=false) do
  3175. begin
  3176. if FoundNonSeparator then
  3177. begin
  3178. if IsWordSeparator(Line[X+1]) then
  3179. begin
  3180. Inc(X);
  3181. GotIt:=true;
  3182. Break;
  3183. end;
  3184. end
  3185. else
  3186. if not IsWordSeparator(Line[X+1]) then
  3187. FoundNonSeparator:=true;
  3188. Dec(X);
  3189. if (X=0) and (IsWordSeparator(Line[1])=false) then
  3190. begin
  3191. GotIt:=true;
  3192. Break;
  3193. end;
  3194. end;
  3195. if GotIt then
  3196. Break;
  3197. X:=0;
  3198. Dec(Y);
  3199. if Y>=0 then
  3200. begin
  3201. X:=length(GetDisplayText(Y));
  3202. Break;
  3203. end;
  3204. end;
  3205. if Y<0 then Y:=0; if X<0 then X:=0;
  3206. SetCurPtr(X,Y);
  3207. end;
  3208. procedure TCustomCodeEditor.WordRight;
  3209. var X, Y: sw_integer;
  3210. Line: string;
  3211. GotIt: boolean;
  3212. begin
  3213. X:=CurPos.X; Y:=CurPos.Y; GotIt:=false;
  3214. while (Y<GetLineCount) do
  3215. begin
  3216. if Y=CurPos.Y then
  3217. begin
  3218. X:=CurPos.X; Inc(X);
  3219. if (X>length(GetDisplayText(Y))-1) then
  3220. begin Inc(Y); X:=0; end;
  3221. end else X:=0;
  3222. Line:=GetDisplayText(Y);
  3223. while (X<=length(Line)+1) and (GotIt=false) and (Line<>'') do
  3224. begin
  3225. if X=length(Line)+1 then begin GotIt:=true; Dec(X); Break end;
  3226. if IsWordSeparator(Line[X]) then
  3227. begin
  3228. while (Y<GetLineCount) and
  3229. (X<=length(Line)) and (IsWordSeparator(Line[X])) do
  3230. begin
  3231. Inc(X);
  3232. if X>=length(Line) then
  3233. begin GotIt:=true; Dec(X); Break; end;
  3234. end;
  3235. if (GotIt=false) and (X<length(Line)) then
  3236. begin
  3237. Dec(X);
  3238. GotIt:=true;
  3239. Break;
  3240. end;
  3241. end;
  3242. Inc(X);
  3243. end;
  3244. if GotIt then Break;
  3245. X:=0;
  3246. Inc(Y);
  3247. if (Y<GetLineCount) then
  3248. begin
  3249. Line:=GetDisplayText(Y);
  3250. if (Line<>'') and (IsWordSeparator(Line[1])=false) then Break;
  3251. end;
  3252. end;
  3253. if Y=GetLineCount then Y:=GetLineCount-1;
  3254. SetCurPtr(X,Y);
  3255. end;
  3256. procedure TCustomCodeEditor.LineStart;
  3257. begin
  3258. SetCurPtr(0,CurPos.Y);
  3259. end;
  3260. procedure TCustomCodeEditor.LineEnd;
  3261. var
  3262. s : string;
  3263. i : longint;
  3264. begin
  3265. if CurPos.Y<GetLineCount then
  3266. begin
  3267. s:=GetDisplayText(CurPos.Y);
  3268. i:=length(s);
  3269. while (i>0) and (s[i]=' ') do
  3270. dec(i);
  3271. SetCurPtr(i,CurPos.Y);
  3272. end
  3273. else
  3274. SetCurPtr(0,CurPos.Y);
  3275. end;
  3276. procedure TCustomCodeEditor.LineUp;
  3277. begin
  3278. if CurPos.Y>0 then
  3279. SetCurPtr(CurPos.X,CurPos.Y-1);
  3280. end;
  3281. procedure TCustomCodeEditor.LineDown;
  3282. begin
  3283. if (CurPos.Y<GetLineCount-1) then
  3284. SetCurPtr(CurPos.X,CurPos.Y+1);
  3285. end;
  3286. procedure TCustomCodeEditor.PageUp;
  3287. begin
  3288. ScrollTo(Delta.X,Max(Delta.Y-Size.Y,0));
  3289. SetCurPtr(CurPos.X,Max(0,CurPos.Y-(Size.Y)));
  3290. end;
  3291. procedure TCustomCodeEditor.PageDown;
  3292. begin
  3293. ScrollTo(Delta.X,Min(Delta.Y+Size.Y,GetLineCount-1));
  3294. SetCurPtr(CurPos.X,Min(GetLineCount-1,CurPos.Y+(Size.Y{-1})));
  3295. end;
  3296. procedure TCustomCodeEditor.TextStart;
  3297. begin
  3298. SetCurPtr(0,0);
  3299. end;
  3300. procedure TCustomCodeEditor.TextEnd;
  3301. var s : string;
  3302. i : longint;
  3303. begin
  3304. s:=GetDisplayText(GetLineCount-1);
  3305. i:=length(s);
  3306. while (i>0) and (s[i]=' ') do
  3307. dec(i);
  3308. SetCurPtr(i,GetLineCount-1);
  3309. end;
  3310. procedure TCustomCodeEditor.WindowStart;
  3311. begin
  3312. SetCurPtr(CurPos.X,Delta.Y);
  3313. end;
  3314. procedure TCustomCodeEditor.WindowEnd;
  3315. begin
  3316. SetCurPtr(CurPos.X,Delta.Y+Size.Y-1);
  3317. end;
  3318. procedure TCustomCodeEditor.JumpSelStart;
  3319. begin
  3320. if ValidBlock then
  3321. SetCurPtr(SelStart.X,SelStart.Y);
  3322. end;
  3323. procedure TCustomCodeEditor.JumpSelEnd;
  3324. begin
  3325. if ValidBlock then
  3326. SetCurPtr(SelEnd.X,SelEnd.Y);
  3327. end;
  3328. procedure TCustomCodeEditor.JumpMark(MarkIdx: integer);
  3329. begin
  3330. if (MarkIdx<Low(Bookmarks)) or (MarkIdx>High(Bookmarks)) then
  3331. begin ErrorBox(FormatStrInt(msg_invalidmarkindex,MarkIdx),nil); Exit; end;
  3332. with Bookmarks[MarkIdx] do
  3333. if Valid=false then
  3334. InformationBox(FormatStrInt(msg_marknotset,MarkIdx),nil)
  3335. else
  3336. SetCurPtr(Pos.X,Pos.Y);
  3337. end;
  3338. procedure TCustomCodeEditor.DefineMark(MarkIdx: integer);
  3339. begin
  3340. if (MarkIdx<Low(Bookmarks)) or (MarkIdx>High(Bookmarks)) then
  3341. begin
  3342. ErrorBox(FormatStrInt(msg_invalidmarkindex,MarkIdx),nil);
  3343. Exit;
  3344. end;
  3345. with Bookmarks[MarkIdx] do
  3346. begin
  3347. Pos:=CurPos;
  3348. Valid:=true;
  3349. end;
  3350. end;
  3351. procedure TCustomCodeEditor.JumpToLastCursorPos;
  3352. begin
  3353. NotImplemented;
  3354. end;
  3355. procedure TCustomCodeEditor.UpperCase;
  3356. var StartP,EndP: TPoint;
  3357. begin
  3358. if ValidBlock=false then Exit;
  3359. GetSelectionArea(StartP,EndP);
  3360. ChangeCaseArea(StartP,EndP,caToUpperCase);
  3361. end;
  3362. procedure TCustomCodeEditor.LowerCase;
  3363. var StartP,EndP: TPoint;
  3364. begin
  3365. if ValidBlock=false then Exit;
  3366. GetSelectionArea(StartP,EndP);
  3367. ChangeCaseArea(StartP,EndP,caToLowerCase);
  3368. end;
  3369. procedure TCustomCodeEditor.ToggleCase;
  3370. var StartP,EndP: TPoint;
  3371. begin
  3372. if ValidBlock=false then Exit;
  3373. GetSelectionArea(StartP,EndP);
  3374. ChangeCaseArea(StartP,EndP,caToggleCase);
  3375. end;
  3376. procedure TCustomCodeEditor.WordLowerCase;
  3377. var StartP,EndP: TPoint;
  3378. begin
  3379. if GetCurrentWordArea(StartP,EndP)=false then Exit;
  3380. ChangeCaseArea(StartP,EndP,caToLowerCase);
  3381. end;
  3382. procedure TCustomCodeEditor.WordUpperCase;
  3383. var StartP,EndP: TPoint;
  3384. begin
  3385. if GetCurrentWordArea(StartP,EndP)=false then Exit;
  3386. ChangeCaseArea(StartP,EndP,caToUpperCase);
  3387. end;
  3388. procedure TCustomCodeEditor.ChangeCaseArea(StartP,EndP: TPoint; CaseAction: TCaseAction);
  3389. var Y,X: sw_integer;
  3390. X1,X2: sw_integer;
  3391. S: string;
  3392. C: char;
  3393. begin
  3394. Lock;
  3395. for Y:=StartP.Y to EndP.Y do
  3396. begin
  3397. S:=GetDisplayText(Y);
  3398. { Pierre, please implement undo here! Gabor }
  3399. X1:=0; X2:=length(S)-1;
  3400. if Y=StartP.Y then X1:=StartP.X;
  3401. if Y=EndP.Y then X2:=EndP.X;
  3402. for X:=X1 to X2 do
  3403. begin
  3404. C:=S[X+1];
  3405. case CaseAction of
  3406. caToLowerCase : C:=LowCase(C);
  3407. caToUpperCase : C:=UpCase(C);
  3408. caToggleCase : if C in['a'..'z'] then
  3409. C:=Upcase(C)
  3410. else
  3411. C:=LowCase(C);
  3412. end;
  3413. S[X+1]:=C;
  3414. end;
  3415. SetDisplayText(Y,S);
  3416. end;
  3417. UpdateAttrsRange(StartP.Y,EndP.Y,attrAll);
  3418. DrawLines(CurPos.Y);
  3419. SetModified(true);
  3420. UnLock;
  3421. end;
  3422. procedure TCustomCodeEditor.InsertOptions;
  3423. begin
  3424. { Abstract }
  3425. NotImplemented;
  3426. end;
  3427. procedure TCustomCodeEditor.FindMatchingDelimiter(ScanForward: boolean);
  3428. const OpenSymbols : string[6] = '[{(<''"';
  3429. CloseSymbols : string[6] = ']})>''"';
  3430. var SymIdx: integer;
  3431. LineText,LineAttr: string;
  3432. CurChar: char;
  3433. X,Y: sw_integer;
  3434. LineCount: sw_integer;
  3435. JumpPos: TPoint;
  3436. BracketLevel: integer;
  3437. begin
  3438. JumpPos.X:=-1; JumpPos.Y:=-1;
  3439. LineText:=GetDisplayText(CurPos.Y);
  3440. LineText:=copy(LineText,CurPos.X+1,1);
  3441. if LineText='' then Exit;
  3442. CurChar:=LineText[1];
  3443. Y:=CurPos.Y; X:=CurPos.X; LineCount:=0;
  3444. BracketLevel:=1;
  3445. if ScanForward then
  3446. begin
  3447. SymIdx:=Pos(CurChar,OpenSymbols);
  3448. if SymIdx=0 then Exit;
  3449. repeat
  3450. Inc(LineCount);
  3451. GetDisplayTextFormat(Y,LineText,LineAttr);
  3452. if LineCount<>1 then X:=-1;
  3453. repeat
  3454. Inc(X);
  3455. if X<length(LineText) then
  3456. if copy(LineAttr,X+1,1)<>chr(attrComment) then
  3457. if (LineText[X+1]=CloseSymbols[SymIdx]) and (BracketLevel=1) then
  3458. begin
  3459. JumpPos.X:=X; JumpPos.Y:=Y;
  3460. end
  3461. else
  3462. if LineText[X+1]=OpenSymbols[SymIdx] then
  3463. Inc(BracketLevel)
  3464. else
  3465. if LineText[X+1]=CloseSymbols[SymIdx] then
  3466. if BracketLevel>1 then
  3467. Dec(BracketLevel);
  3468. until (X>=length(LineText)) or (JumpPos.X<>-1);
  3469. Inc(Y);
  3470. until (Y>=GetLineCount) or (JumpPos.X<>-1);
  3471. end
  3472. else
  3473. begin
  3474. SymIdx:=Pos(CurChar,CloseSymbols);
  3475. if SymIdx=0 then Exit;
  3476. repeat
  3477. Inc(LineCount);
  3478. GetDisplayTextFormat(Y,LineText,LineAttr);
  3479. if LineCount<>1 then X:=length(LineText);
  3480. repeat
  3481. Dec(X);
  3482. if X>0 then
  3483. if copy(LineAttr,X+1,1)<>chr(attrComment) then
  3484. if (LineText[X+1]=OpenSymbols[SymIdx]) and (BracketLevel=1) then
  3485. begin
  3486. JumpPos.X:=X; JumpPos.Y:=Y;
  3487. end
  3488. else
  3489. if LineText[X+1]=CloseSymbols[SymIdx] then
  3490. Inc(BracketLevel)
  3491. else
  3492. if LineText[X+1]=OpenSymbols[SymIdx] then
  3493. if BracketLevel>1 then
  3494. Dec(BracketLevel);
  3495. until (X<0) or (JumpPos.X<>-1);
  3496. Dec(Y);
  3497. until (Y<0) or (JumpPos.X<>-1);
  3498. end;
  3499. if JumpPos.X<>-1 then
  3500. begin
  3501. SetCurPtr(JumpPos.X,JumpPos.Y);
  3502. TrackCursor(true);
  3503. end;
  3504. end;
  3505. function TCustomCodeEditor.InsertNewLine: Sw_integer;
  3506. var Ind: Sw_integer;
  3507. S,IndentStr: string;
  3508. procedure CalcIndent(LineOver: Sw_integer);
  3509. begin
  3510. if (LineOver<0) or (LineOver>GetLineCount) then Ind:=0 else
  3511. begin
  3512. IndentStr:=GetLineText(LineOver);
  3513. Ind:=0;
  3514. while (Ind<length(IndentStr)) and (IndentStr[Ind+1]=' ') do
  3515. Inc(Ind);
  3516. end;
  3517. IndentStr:=CharStr(' ',Ind);
  3518. end;
  3519. var {SelBack: sw_integer;}
  3520. SCP: TPoint;
  3521. HoldUndo : Boolean;
  3522. begin
  3523. if IsReadOnly then begin InsertNewLine:=-1; Exit; end;
  3524. Lock;
  3525. SCP:=CurPos;
  3526. HoldUndo:=GetStoreUndo;
  3527. SetStoreUndo(false);
  3528. if CurPos.Y<GetLineCount then S:=GetLineText(CurPos.Y) else S:='';
  3529. if Overwrite=false then
  3530. begin
  3531. { SelBack:=0;}
  3532. if GetLineCount>0 then
  3533. begin
  3534. S:=GetDisplayText(CurPos.Y);
  3535. { SelBack:=length(S)-SelEnd.X;}
  3536. SetDisplayText(CurPos.Y,RTrim(S,not IsFlagSet(efUseTabCharacters)));
  3537. end;
  3538. SetDisplayText(CurPos.Y,copy(S,1,CurPos.X-1+1));
  3539. CalcIndent(CurPos.Y);
  3540. InsertLine(CurPos.Y+1,IndentStr+copy(S,CurPos.X+1,High(S)));
  3541. LimitsChanged;
  3542. (* if PointOfs(SelStart)<>PointOfs(SelEnd) then { !!! check it - it's buggy !!! }
  3543. begin SelEnd.Y:=CurPos.Y+1; SelEnd.X:=length(GetLineText(CurPos.Y+1))-SelBack; end;*)
  3544. UpdateAttrs(CurPos.Y,attrAll);
  3545. SetCurPtr(Ind,CurPos.Y+1);
  3546. {$ifdef Undo}
  3547. SetStoreUndo(HoldUndo);
  3548. Addaction(eaInsertLine,SCP,CurPos,IndentStr);
  3549. SetStoreUndo(false);
  3550. {$endif Undo}
  3551. AdjustSelection(CurPos.X-SCP.X,CurPos.Y-SCP.Y);
  3552. end else
  3553. begin
  3554. CalcIndent(CurPos.Y);
  3555. if CurPos.Y=GetLineCount-1 then
  3556. begin
  3557. AddLine(IndentStr);
  3558. AdjustSelection(0,1);
  3559. LimitsChanged;
  3560. {$ifdef Undo}
  3561. SetStoreUndo(HoldUndo);
  3562. UpdateAttrs(CurPos.Y,attrAll);
  3563. SetCurPtr(Ind,CurPos.Y+1);
  3564. Addaction(eaInsertLine,SCP,CurPos,IndentStr);
  3565. SetStoreUndo(false);
  3566. {$endif Undo}
  3567. end
  3568. else
  3569. begin
  3570. UpdateAttrs(CurPos.Y,attrAll);
  3571. SetStoreUndo(HoldUndo);
  3572. SetCurPtr(Ind,CurPos.Y+1);
  3573. SetStoreUndo(false);
  3574. end;
  3575. end;
  3576. DrawLines(CurPos.Y);
  3577. SetStoreUndo(HoldUndo);
  3578. SetModified(true);
  3579. Unlock;
  3580. end;
  3581. procedure TCustomCodeEditor.BreakLine;
  3582. begin
  3583. NotImplemented; Exit;
  3584. end;
  3585. procedure TCustomCodeEditor.BackSpace;
  3586. var S,PreS: string;
  3587. OI,CI,CP,Y,TX: Sw_integer;
  3588. SCP,SC1 : TPoint;
  3589. HoldUndo : Boolean;
  3590. begin
  3591. if IsReadOnly then Exit;
  3592. Lock;
  3593. SCP:=CurPos;
  3594. HoldUndo:=GetStoreUndo;
  3595. SetStoreUndo(false);
  3596. if CurPos.X=0 then
  3597. begin
  3598. if CurPos.Y>0 then
  3599. begin
  3600. S:=GetLineText(CurPos.Y-1);
  3601. SetLineText(CurPos.Y-1,S+GetLineText(CurPos.Y));
  3602. SC1.X:=Length(S);SC1.Y:=CurPOS.Y-1;
  3603. SetStoreUndo(HoldUndo);
  3604. AddAction(eaDeleteLine,SCP,SC1,GetLineText(CurPos.Y));
  3605. SetStoreUndo(false);
  3606. DeleteLine(CurPos.Y);
  3607. LimitsChanged;
  3608. SetCurPtr(length(S),CurPos.Y-1);
  3609. end;
  3610. end
  3611. else
  3612. begin
  3613. S:=GetDisplayText(CurPos.Y);
  3614. CP:=CurPos.X-1;
  3615. if IsFlagSet(efBackspaceUnindents) then
  3616. if Trim(copy(S,1,CP+1))='' then
  3617. begin
  3618. Y:=CurPos.Y;
  3619. while (Y>0) do
  3620. begin
  3621. Dec(Y);
  3622. PreS:=GetDisplayText(Y);
  3623. if Trim(copy(PreS,1,CP+1))<>'' then Break;
  3624. end;
  3625. if Y<0 then PreS:='';
  3626. { while (CP>0) and
  3627. ( (CP>length(S)) or (S[CP]=' ') ) and
  3628. ( (CP>length(PreS)) or (PreS[CP]<>' ') ) do
  3629. Dec(CP);}
  3630. TX:=0;
  3631. while (TX<length(PreS)) and (PreS[TX+1]=' ') do
  3632. Inc(TX);
  3633. if TX<CP then CP:=TX;
  3634. end;
  3635. S:=GetLineText(CurPos.Y);
  3636. OI:=LinePosToCharIdx(CurPos.Y,CurPos.X);
  3637. CI:=LinePosToCharIdx(CurPos.Y,CP);
  3638. SetLineText(CurPos.Y,copy(S,1,CI-1)+copy(S,OI,High(S)));
  3639. SetCurPtr(CP,CurPos.Y);
  3640. {$ifdef Undo}
  3641. SetStoreUndo(HoldUndo);
  3642. Addaction(eaDeleteText,SCP,CurPos,Copy(S,CI,OI-CI));
  3643. SetStoreUndo(false);
  3644. {$endif Undo}
  3645. end;
  3646. UpdateAttrs(CurPos.Y,attrAll);
  3647. AdjustSelection(CurPos.X-SCP.X,CurPos.Y-SCP.Y);
  3648. DrawLines(CurPos.Y);
  3649. SetStoreUndo(HoldUndo);
  3650. SetModified(true);
  3651. Unlock;
  3652. end;
  3653. procedure TCustomCodeEditor.DelChar;
  3654. var S: string;
  3655. SDX,SDY,CI : sw_integer;
  3656. HoldUndo : boolean;
  3657. SCP : TPoint;
  3658. begin
  3659. if IsReadOnly then Exit;
  3660. Lock;
  3661. HoldUndo:=GetStoreUndo;
  3662. SetStoreUndo(false);
  3663. S:=GetLineText(CurPos.Y);
  3664. if CurPos.X>=length(S) then
  3665. begin
  3666. if CurPos.Y<GetLineCount-1 then
  3667. begin
  3668. SetLineText(CurPos.Y,S+CharStr(' ',CurPOS.X-Length(S))+GetLineText(CurPos.Y+1));
  3669. SetStoreUndo(HoldUndo);
  3670. SCP.X:=0;SCP.Y:=CurPos.Y+1;
  3671. AddAction(eaDeleteLine,SCP,CurPos,GetLineText(CurPos.Y+1));
  3672. SetStoreUndo(false);
  3673. DeleteLine(CurPos.Y+1);
  3674. LimitsChanged;
  3675. SDX:=0; SDY:=-1;
  3676. end;
  3677. end
  3678. else
  3679. begin
  3680. { Problem if S[CurPos.X+1]=TAB !! PM }
  3681. CI:=LinePosToCharIdx(CurPos.Y,CurPos.X);
  3682. if S[CI]=TAB then
  3683. begin
  3684. S:=Copy(S,1,CI-1)+CharStr(' ',GetTabSize-1)+Copy(S,CI+1,High(S));
  3685. {$ifdef Undo}
  3686. SetStoreUndo(HoldUndo);
  3687. Addaction(eaDeleteText,CurPos,CurPos,' ');
  3688. SetStoreUndo(false);
  3689. {$endif Undo}
  3690. end
  3691. else
  3692. begin
  3693. {$ifdef Undo}
  3694. SetStoreUndo(HoldUndo);
  3695. Addaction(eaDeleteText,CurPos,CurPos,S[CI]);
  3696. SetStoreUndo(false);
  3697. {$endif Undo}
  3698. Delete(S,CI,1);
  3699. end;
  3700. SetLineText(CurPos.Y,S);
  3701. SDX:=-1; SDY:=0;
  3702. end;
  3703. SetCurPtr(CurPos.X,CurPos.Y);
  3704. UpdateAttrs(CurPos.Y,attrAll);
  3705. AdjustSelection(SDX,SDY);
  3706. DrawLines(CurPos.Y);
  3707. SetStoreUndo(HoldUndo);
  3708. SetModified(true);
  3709. Unlock;
  3710. end;
  3711. procedure TCustomCodeEditor.DelWord;
  3712. var
  3713. SP,EP : TPoint;
  3714. SelSize : sw_integer;
  3715. begin
  3716. if IsReadOnly then Exit;
  3717. Lock;
  3718. SP:=SelStart;
  3719. EP:=SelEnd;
  3720. SelectWord;
  3721. SelSize:=SelEnd.X-SelStart.X;
  3722. DelSelect;
  3723. SetSelection(SP,EP);
  3724. AdjustSelectionPos(CurPos.X,CurPos.Y,SelSize,0);
  3725. SetModified(true);
  3726. Unlock;
  3727. end;
  3728. procedure TCustomCodeEditor.DelStart;
  3729. var S: string;
  3730. begin
  3731. if IsReadOnly then Exit;
  3732. Lock;
  3733. S:=GetLineText(CurPos.Y);
  3734. if (S<>'') and (CurPos.X<>0) then
  3735. begin
  3736. SetLineText(CurPos.Y,copy(S,LinePosToCharIdx(CurPos.Y,CurPos.X),High(S)));
  3737. SetCurPtr(0,CurPos.Y);
  3738. UpdateAttrs(CurPos.Y,attrAll);
  3739. DrawLines(CurPos.Y);
  3740. SetModified(true);
  3741. end;
  3742. Unlock;
  3743. end;
  3744. procedure TCustomCodeEditor.DelEnd;
  3745. var S: string;
  3746. begin
  3747. if IsReadOnly then Exit;
  3748. Lock;
  3749. S:=GetLineText(CurPos.Y);
  3750. if (S<>'') and (CurPos.X<>length(S)) then
  3751. begin
  3752. SetLineText(CurPos.Y,copy(S,1,LinePosToCharIdx(CurPos.Y,CurPos.X)-1));
  3753. SetCurPtr(CurPos.X,CurPos.Y);
  3754. UpdateAttrs(CurPos.Y,attrAll);
  3755. DrawLines(CurPos.Y);
  3756. SetModified(true);
  3757. end;
  3758. Unlock;
  3759. end;
  3760. procedure TCustomCodeEditor.DelLine;
  3761. var
  3762. HoldUndo : boolean;
  3763. { SP : TPoint;}
  3764. begin
  3765. if IsReadOnly then Exit;
  3766. Lock;
  3767. if GetLineCount>0 then
  3768. begin
  3769. { SP:=CurPos;}
  3770. DeleteLine(CurPos.Y);
  3771. HoldUndo:=GetStoreUndo;
  3772. SetStoreUndo(false);
  3773. LimitsChanged;
  3774. AdjustSelection(0,-1);
  3775. SetCurPtr(0,CurPos.Y);
  3776. UpdateAttrs(Max(0,CurPos.Y-1),attrAll);
  3777. DrawLines(CurPos.Y);
  3778. { put this back !!!!!!
  3779. If HoldUndo then
  3780. with Core^.UndoList^.At(Core^.UndoList^.count-1)^ do
  3781. begin
  3782. EndPos:=CurPos;
  3783. StartPos:=SP;
  3784. end;
  3785. }
  3786. SetStoreUndo(HoldUndo);
  3787. SetModified(true);
  3788. end;
  3789. Unlock;
  3790. end;
  3791. procedure TCustomCodeEditor.InsMode;
  3792. begin
  3793. SetInsertMode(Overwrite);
  3794. end;
  3795. function TCustomCodeEditor.GetCurrentWordArea(var StartP,EndP: TPoint): boolean;
  3796. const WordChars = ['A'..'Z','a'..'z','0'..'9','_'];
  3797. var P : TPoint;
  3798. S : String;
  3799. StartPos,EndPos : byte;
  3800. OK: boolean;
  3801. begin
  3802. P:=CurPos;
  3803. S:=GetLineText(P.Y);
  3804. StartPos:=P.X+1;
  3805. EndPos:=StartPos;
  3806. OK:=(S[StartPos] in WordChars);
  3807. if OK then
  3808. begin
  3809. While (StartPos>0) and (S[StartPos-1] in WordChars) do
  3810. Dec(StartPos);
  3811. While (EndPos<Length(S)) and (S[EndPos+1] in WordChars) do
  3812. Inc(EndPos);
  3813. StartP.X:=StartPos-1; StartP.Y:=CurPos.Y;
  3814. EndP.X:=EndPos-1; EndP.Y:=CurPos.Y;
  3815. end;
  3816. GetCurrentWordArea:=OK;
  3817. end;
  3818. function TCustomCodeEditor.GetCurrentWord : string;
  3819. var S: string;
  3820. StartP,EndP: TPoint;
  3821. begin
  3822. if GetCurrentWordArea(StartP,EndP)=false then
  3823. S:=''
  3824. else
  3825. begin
  3826. S:=GetLineText(StartP.Y);
  3827. S:=copy(S,StartP.X+1,EndP.X-StartP.X+1);
  3828. end;
  3829. GetCurrentWord:=S;
  3830. end;
  3831. procedure TCustomCodeEditor.StartSelect;
  3832. var P1,P2: TPoint;
  3833. begin
  3834. if ValidBlock=false then
  3835. begin
  3836. { SetSelection(SelStart,Limit);}
  3837. P1:=CurPos; P1.X:=0; P2:=CurPos; {P2.X:=length(GetLineText(P2.Y))+1;}
  3838. SetSelection(P1,P2);
  3839. end
  3840. else
  3841. SetSelection(CurPos,SelEnd);
  3842. if PointOfs(SelEnd)<PointOfs(SelStart) then
  3843. SetSelection(SelStart,SelStart);
  3844. CheckSels;
  3845. DrawView;
  3846. end;
  3847. procedure TCustomCodeEditor.EndSelect;
  3848. var P: TPoint;
  3849. LS: sw_integer;
  3850. begin
  3851. P:=CurPos;
  3852. { P.X:=Min(SelEnd.X,length(GetLineText(SelEnd.Y)));}
  3853. LS:=length(GetLineText(SelEnd.Y));
  3854. if LS<P.X then P.X:=LS;
  3855. CheckSels;
  3856. SetSelection(SelStart,P);
  3857. DrawView;
  3858. end;
  3859. procedure TCustomCodeEditor.DelSelect;
  3860. var LineDelta, LineCount, CurLine: Sw_integer;
  3861. StartX,EndX,LastX: Sw_integer;
  3862. S: string;
  3863. SPos : TPoint;
  3864. begin
  3865. if IsReadOnly or (ValidBlock=false) then Exit;
  3866. Lock;
  3867. LineCount:=(SelEnd.Y-SelStart.Y)+1;
  3868. LineDelta:=0; LastX:=CurPos.X;
  3869. CurLine:=SelStart.Y;
  3870. { single line : easy }
  3871. if LineCount=1 then
  3872. begin
  3873. S:=GetDisplayText(CurLine);
  3874. StartX:=SelStart.X;
  3875. EndX:=SelEnd.X;
  3876. SetDisplayText(CurLine,RExpand(copy(S,1,StartX),StartX)
  3877. +copy(S,EndX+1,High(S)));
  3878. if GetStoreUndo then
  3879. begin
  3880. SPos.X:=StartX;
  3881. SPos.Y:=CurLine;
  3882. AddAction(eaDeleteText,SPos,SPos,Copy(S,StartX+1,EndX-StartX));
  3883. end;
  3884. Inc(CurLine);
  3885. LastX:=SelStart.X;
  3886. end
  3887. { several lines : a bit less easy }
  3888. else
  3889. begin
  3890. S:=GetDisplayText(CurLine);
  3891. StartX:=SelStart.X;
  3892. EndX:=SelEnd.X;
  3893. SetDisplayText(CurLine,RExpand(copy(S,1,StartX),StartX)
  3894. +copy(GetDisplayText(CurLine+LineCount-1),EndX+1,High(S)));
  3895. if GetStoreUndo then
  3896. begin
  3897. SPos.X:=StartX;
  3898. SPos.Y:=CurLine;
  3899. AddAction(eaDeleteText,SPos,SPos,Copy(S,StartX+1,High(S)));
  3900. S:=GetDisplayText(CurLine+LineCount-1);
  3901. end;
  3902. Inc(CurLine);
  3903. Inc(LineDelta);
  3904. LastX:=SelStart.X;
  3905. while (LineDelta<LineCount) do
  3906. begin
  3907. { delete the complete line }
  3908. DeleteLine(CurLine);
  3909. Inc(LineDelta);
  3910. end;
  3911. if GetStoreUndo then
  3912. begin
  3913. AddAction(eaInsertText,SPos,SPos,Copy(S,EndX+1,High(S)));
  3914. end;
  3915. end;
  3916. HideSelect;
  3917. SetCurPtr(LastX,CurLine-1);
  3918. UpdateAttrs(CurPos.Y,attrAll);
  3919. DrawLines(CurPos.Y);
  3920. SetModified(true);
  3921. UnLock;
  3922. end;
  3923. procedure TCustomCodeEditor.HideSelect;
  3924. begin
  3925. SetSelection(CurPos,CurPos);
  3926. DrawLines(Delta.Y);
  3927. end;
  3928. procedure TCustomCodeEditor.CopyBlock;
  3929. var Temp: PCodeEditor;
  3930. R: TRect;
  3931. begin
  3932. if IsReadOnly or (ValidBlock=false) then Exit;
  3933. Lock;
  3934. GetExtent(R);
  3935. New(Temp, Init(R, nil, nil, nil,nil));
  3936. Temp^.InsertFrom(@Self);
  3937. (* Temp^.SelectAll(true);
  3938. { this selects one line too much because
  3939. we have a empty line at creation to avoid
  3940. negative line problems so we need to decrease SelEnd.Y }
  3941. Dec(Temp^.SelEnd.Y);*)
  3942. InsertFrom(Temp);
  3943. Dispose(Temp, Done);
  3944. UnLock;
  3945. end;
  3946. procedure TCustomCodeEditor.MoveBlock;
  3947. var Temp: PCodeEditor;
  3948. R: TRect;
  3949. OldPos: TPoint;
  3950. begin
  3951. if IsReadOnly then Exit;
  3952. if (SelStart.X=SelEnd.X) and (SelStart.Y=SelEnd.Y) then Exit;
  3953. Lock;
  3954. GetExtent(R);
  3955. New(Temp, Init(R, nil, nil, nil,nil));
  3956. Temp^.InsertFrom(@Self);
  3957. OldPos:=CurPos;
  3958. if CurPos.Y>SelStart.Y then
  3959. Dec(OldPos.Y,Temp^.GetLineCount-1);
  3960. DelSelect;
  3961. SetCurPtr(OldPos.X,OldPos.Y);
  3962. InsertFrom(Temp);
  3963. Dispose(Temp, Done);
  3964. UnLock;
  3965. end;
  3966. procedure TCustomCodeEditor.IndentBlock;
  3967. var
  3968. ey,i : Sw_integer;
  3969. S : String;
  3970. begin
  3971. if IsReadOnly then Exit;
  3972. if (SelStart.X=SelEnd.X) and (SelStart.Y=SelEnd.Y) then Exit;
  3973. Lock;
  3974. ey:=selend.y;
  3975. if selend.x=0 then
  3976. dec(ey);
  3977. for i:=selstart.y to ey do
  3978. begin
  3979. S:=GetLineText(i);
  3980. SetLineText(i,' '+S);
  3981. end;
  3982. SetCurPtr(CurPos.X,CurPos.Y);
  3983. UpdateAttrsRange(SelStart.Y,SelEnd.Y,attrAll);
  3984. DrawLines(CurPos.Y);
  3985. SetModified(true);
  3986. UnLock;
  3987. end;
  3988. procedure TCustomCodeEditor.UnindentBlock;
  3989. var
  3990. ey,i : Sw_integer;
  3991. S : String;
  3992. begin
  3993. if IsReadOnly then Exit;
  3994. if (SelStart.X=SelEnd.X) and (SelStart.Y=SelEnd.Y) then Exit;
  3995. Lock;
  3996. ey:=selend.y;
  3997. if selend.x=0 then
  3998. dec(ey);
  3999. for i:=selstart.y to ey do
  4000. begin
  4001. S:=GetLineText(i);
  4002. if (length(s)>1) and (S[1]=' ') then
  4003. Delete(s,1,1);
  4004. SetLineText(i,S);
  4005. end;
  4006. SetCurPtr(CurPos.X,CurPos.Y);
  4007. UpdateAttrsRange(SelStart.Y,SelEnd.Y,attrAll);
  4008. DrawLines(CurPos.Y);
  4009. SetModified(true);
  4010. UnLock;
  4011. end;
  4012. procedure TCustomCodeEditor.SelectWord;
  4013. const WordChars = ['A'..'Z','a'..'z','0'..'9','_'];
  4014. var S : String;
  4015. StartPos,EndPos : byte;
  4016. A,B: TPoint;
  4017. begin
  4018. A:=CurPos;
  4019. B:=CurPos;
  4020. S:=GetLineText(A.Y);
  4021. StartPos:=A.X+1;
  4022. EndPos:=StartPos;
  4023. if not (S[StartPos] in WordChars) then
  4024. exit
  4025. else
  4026. begin
  4027. While (StartPos>0) and (S[StartPos-1] in WordChars) do
  4028. Dec(StartPos);
  4029. While (EndPos<Length(S)) and (S[EndPos+1] in WordChars) do
  4030. Inc(EndPos);
  4031. A.X:=StartPos-1;
  4032. B.X:=EndPos;
  4033. SetSelection(A,B);
  4034. end;
  4035. end;
  4036. procedure TCustomCodeEditor.SelectLine;
  4037. var A,B: TPoint;
  4038. begin
  4039. if CurPos.Y<GetLineCount then
  4040. begin
  4041. A.Y:=CurPos.Y; A.X:=0;
  4042. B.Y:=CurPos.Y+1; B.X:=0;
  4043. SetSelection(A,B);
  4044. end;
  4045. end;
  4046. procedure TCustomCodeEditor.WriteBlock;
  4047. var FileName: string;
  4048. S: PBufStream;
  4049. begin
  4050. if ValidBlock=false then Exit;
  4051. FileName:='';
  4052. if EditorDialog(edWriteBlock, @FileName) <> cmCancel then
  4053. begin
  4054. FileName := FExpand(FileName);
  4055. New(S, Init(FileName, stCreate, 4096));
  4056. if (S=nil) or (S^.Status<>stOK) then
  4057. EditorDialog(edCreateError,@FileName)
  4058. else
  4059. if SaveAreaToStream(S,SelStart,SelEnd)=false then
  4060. EditorDialog(edWriteError,@FileName);
  4061. if Assigned(S) then Dispose(S, Done);
  4062. end;
  4063. end;
  4064. procedure TCustomCodeEditor.ReadBlock;
  4065. var FileName: string;
  4066. S: PBufStream;
  4067. E: PCodeEditor;
  4068. R: TRect;
  4069. begin
  4070. FileName:='';
  4071. if EditorDialog(edReadBlock, @FileName) <> cmCancel then
  4072. begin
  4073. FileName := FExpand(FileName);
  4074. New(S, Init(FileName, stOpenRead, 4096));
  4075. if (S=nil) or (S^.Status<>stOK) then
  4076. EditorDialog(edReadError,@FileName)
  4077. else
  4078. begin
  4079. R.Assign(0,0,0,0);
  4080. New(E, Init(R,nil,nil,nil,nil));
  4081. if E^.LoadFromStream(S)=false then
  4082. EditorDialog(edReadError,@FileName)
  4083. else
  4084. begin
  4085. E^.SelectAll(true);
  4086. Self.InsertFrom(E);
  4087. end;
  4088. Dispose(E, Done);
  4089. end;
  4090. if Assigned(S) then Dispose(S, Done);
  4091. end;
  4092. end;
  4093. procedure TCustomCodeEditor.PrintBlock;
  4094. begin
  4095. NotImplemented; Exit;
  4096. end;
  4097. procedure TCustomCodeEditor.ExpandCodeTemplate;
  4098. var Line,ShortCut: string;
  4099. X,Y,I,LineIndent: sw_integer;
  4100. CodeLines: PUnsortedStringCollection;
  4101. CanJump: boolean;
  4102. begin
  4103. {
  4104. The usage of editing primitives in this routine make it pretty slow, but
  4105. its speed is still acceptable and they make the implementation of Undo
  4106. much easier... - Gabor
  4107. }
  4108. if IsReadOnly then Exit;
  4109. Lock;
  4110. Line:=GetDisplayText(CurPos.Y);
  4111. X:=CurPos.X; ShortCut:='';
  4112. if X<=length(Line) then
  4113. while (X>0) and (Line[X] in (NumberChars+AlphaChars)) do
  4114. begin
  4115. ShortCut:=Line[X]+ShortCut;
  4116. Dec(X);
  4117. end;
  4118. if ShortCut<>'' then
  4119. begin
  4120. New(CodeLines, Init(10,10));
  4121. if TranslateCodeTemplate(ShortCut,CodeLines) then
  4122. begin
  4123. LineIndent:=X;
  4124. SetCurPtr(X,CurPos.Y);
  4125. for I:=1 to length(ShortCut) do
  4126. DelChar;
  4127. for Y:=0 to CodeLines^.Count-1 do
  4128. begin
  4129. CanJump:=false;
  4130. if Y>0 then
  4131. begin
  4132. CanJump:=Trim(GetLineText(CurPos.Y))='';
  4133. if CanJump=false then
  4134. begin
  4135. for X:=1 to LineIndent do { indent template lines to align }
  4136. AddChar(' '); { them to the first line }
  4137. end
  4138. else
  4139. SetCurPtr(CurPos.X+LineIndent,CurPos.Y);
  4140. end;
  4141. Line:=CodeLines^.At(Y)^;
  4142. for X:=1 to length(Line) do
  4143. AddChar(Line[X]);
  4144. if Y<CodeLines^.Count-1 then
  4145. begin
  4146. InsertNewLine; { line break }
  4147. if CanJump=false then
  4148. begin
  4149. while CurPos.X>0 do { unindent }
  4150. begin
  4151. SetCurPtr(CurPos.X-1,CurPos.Y);
  4152. DelChar;
  4153. end;
  4154. end
  4155. else
  4156. SetCurPtr(0,CurPos.Y);
  4157. end;
  4158. end;
  4159. end;
  4160. Dispose(CodeLines, Done);
  4161. end;
  4162. UnLock;
  4163. end;
  4164. procedure TCustomCodeEditor.AddChar(C: char);
  4165. const OpenBrackets : string[10] = '[({';
  4166. CloseBrackets : string[10] = '])}';
  4167. var S,SC,TabS: string;
  4168. BI: byte;
  4169. CI,TabStart,LocTabSize : Sw_integer;
  4170. SP: TPoint;
  4171. HoldUndo : boolean;
  4172. begin
  4173. if IsReadOnly then Exit;
  4174. Lock;
  4175. SP:=CurPos;
  4176. HoldUndo:=GetStoreUndo;
  4177. SetStoreUndo(false);
  4178. if (C<>TAB) or IsFlagSet(efUseTabCharacters) then
  4179. SC:=C
  4180. else
  4181. begin
  4182. LocTabSize:=GetTabSize - (CurPos.X mod GetTabSize);
  4183. if (CurPos.Y<=1) or not IsFlagSet(efAutoIndent) then
  4184. SC:=CharStr(' ',LocTabSize)
  4185. else
  4186. begin
  4187. S:=GetLineText(CurPos.Y-1);
  4188. BI:=CurPos.X+1;
  4189. while (BI<=Length(S)) and (S[BI]=' ') do
  4190. inc(BI);
  4191. if (BI=CurPos.X+1) or (BI>Length(S)) then
  4192. SC:=CharStr(' ',LocTabSize)
  4193. else
  4194. SC:=CharStr(' ',BI-CurPos.X-1);
  4195. end;
  4196. end;
  4197. S:=GetLineText(CurPos.Y);
  4198. if CharIdxToLinePos(CurPos.Y,length(S))<CurPos.X then
  4199. begin
  4200. S:=S+CharStr(' ',CurPos.X-CharIdxToLinePos(CurPos.Y,length(S)){-1});
  4201. SetLineText(CurPos.Y,S);
  4202. end;
  4203. CI:=LinePosToCharIdx(CurPos.Y,CurPos.X);
  4204. if (CI>0) and (S[CI]=TAB) then
  4205. begin
  4206. if CI=1 then
  4207. TabStart:=0
  4208. else
  4209. TabStart:=CharIdxToLinePos(CurPos.Y,CI-1)+1;
  4210. if SC=Tab then TabS:=Tab else
  4211. TabS:=CharStr(' ',CurPos.X-TabStart);
  4212. SetLineText(CurPos.Y,copy(S,1,CI-1)+TabS+SC+copy(S,CI+1,High(S)));
  4213. SetCurPtr(CharIdxToLinePos(CurPos.Y,CI+length(TabS)+length(SC)),CurPos.Y);
  4214. end
  4215. else
  4216. begin
  4217. if Overwrite and (CI<=length(S)) then
  4218. SetLineText(CurPos.Y,copy(S,1,CI-1)+SC+copy(S,CI+length(SC),High(S)))
  4219. else
  4220. SetLineText(CurPos.Y,copy(S,1,CI-1)+SC+copy(S,CI,High(S)));
  4221. SetCurPtr(CharIdxToLinePos(CurPos.Y,CI+length(SC)),CurPos.Y);
  4222. end;
  4223. {$ifdef Undo}
  4224. { must be before CloseBrackets !! }
  4225. SetStoreUndo(HoldUndo);
  4226. Addaction(eaInsertText,SP,CurPos,C);
  4227. SetStoreUndo(false);
  4228. {$endif Undo}
  4229. if IsFlagSet(efAutoBrackets) then
  4230. begin
  4231. BI:=Pos(C,OpenBrackets);
  4232. if (BI>0) then
  4233. begin
  4234. SetStoreUndo(HoldUndo);
  4235. AddChar(CloseBrackets[BI]);
  4236. SetStoreUndo(false);
  4237. SetCurPtr(CurPos.X-1,CurPos.Y);
  4238. end;
  4239. end;
  4240. UpdateAttrs(CurPos.Y,attrAll);
  4241. if GetInsertMode then
  4242. AdjustSelection(CurPos.X-SP.X,CurPos.Y-SP.Y);
  4243. DrawLines(CurPos.Y);
  4244. SetStoreUndo(HoldUndo);
  4245. SetModified(true);
  4246. UnLock;
  4247. end;
  4248. {$ifdef WinClipSupported}
  4249. function TCustomCodeEditor.ClipPasteWin: Boolean;
  4250. var OK: boolean;
  4251. l,i : longint;
  4252. p,p10,p2,p13 : pchar;
  4253. s : string;
  4254. BPos,EPos,StorePos : TPoint;
  4255. first : boolean;
  4256. begin
  4257. Lock;
  4258. OK:=WinClipboardSupported;
  4259. if OK then
  4260. begin
  4261. first:=true;
  4262. StorePos:=CurPos;
  4263. i:=CurPos.Y;
  4264. l:=GetTextWinClipboardSize;
  4265. if l=0 then
  4266. OK:=false
  4267. else
  4268. OK:=GetTextWinClipBoardData(p,l);
  4269. if OK then
  4270. begin
  4271. AddGroupedAction(eaPasteWin);
  4272. p2:=p;
  4273. p13:=strpos(p,#13);
  4274. p10:=strpos(p,#10);
  4275. while assigned(p10) do
  4276. begin
  4277. if p13+1=p10 then
  4278. p13[0]:=#0
  4279. else
  4280. p10[0]:=#0;
  4281. s:=strpas(p2);
  4282. if first then
  4283. begin
  4284. { we need to cut the line in two
  4285. if not at end of line PM }
  4286. InsertNewLine;
  4287. SetCurPtr(StorePos.X,StorePos.Y);
  4288. InsertText(s);
  4289. first:=false;
  4290. end
  4291. else
  4292. begin
  4293. Inc(i);
  4294. InsertLine(i,s);
  4295. BPos.X:=0;BPos.Y:=i;
  4296. EPOS.X:=Length(s);EPos.Y:=i;
  4297. AddAction(eaInsertLine,BPos,EPos,S);
  4298. end;
  4299. if p13+1=p10 then
  4300. p13[0]:=#13
  4301. else
  4302. p10[0]:=#10;
  4303. p2:=@p10[1];
  4304. p13:=strpos(p2,#13);
  4305. p10:=strpos(p2,#10);
  4306. end;
  4307. if strlen(p2)>0 then
  4308. begin
  4309. s:=strpas(p2);
  4310. if not first then
  4311. SetCurPtr(0,i+1);
  4312. InsertText(s);
  4313. end;
  4314. SetCurPtr(StorePos.X,StorePos.Y);
  4315. SetModified(true);
  4316. UpdateAttrs(StorePos.Y,attrAll);
  4317. CloseGroupedAction(eaPasteWin);
  4318. Update;
  4319. { we must free the allocated memory }
  4320. freemem(p,l);
  4321. end;
  4322. end;
  4323. ClipPasteWin:=OK;
  4324. UnLock;
  4325. end;
  4326. function TCustomCodeEditor.ClipCopyWin: Boolean;
  4327. var OK: boolean;
  4328. p,p2 : pchar;
  4329. s : string;
  4330. i,str_begin,str_end,NumLines,PcLength : longint;
  4331. begin
  4332. NumLines:=SelEnd.Y-SelStart.Y;
  4333. if (NumLines>0) or (SelEnd.X>SelStart.X) then
  4334. Inc(NumLines);
  4335. if NumLines=0 then
  4336. exit;
  4337. Lock;
  4338. { First calculate needed size }
  4339. { for newlines first + 1 for terminal #0 }
  4340. PcLength:=Length(EOL)*(NumLines-1)+1;
  4341. { overestimated but can not be that big PM }
  4342. for i:=SelStart.Y to SelEnd.Y do
  4343. PCLength:=PCLength+Length(GetLineText(i));
  4344. getmem(p,PCLength);
  4345. i:=SelStart.Y;
  4346. s:=GetLineText(i);
  4347. str_begin:=LinePosToCharIdx(i,SelStart.X);
  4348. if SelEnd.Y>SelStart.Y then
  4349. str_end:=High(S)
  4350. else
  4351. str_end:=LinePosToCharIdx(i,SelEnd.X)-1;
  4352. s:=copy(s,str_begin,str_end-str_begin+1);
  4353. strpcopy(p,s);
  4354. p2:=strend(p);
  4355. inc(i);
  4356. while i<SelEnd.Y do
  4357. begin
  4358. strpcopy(p2,EOL+GetLineText(i));
  4359. p2:=strend(p2);
  4360. Inc(i);
  4361. end;
  4362. if SelEnd.Y>SelStart.Y then
  4363. begin
  4364. s:=copy(GetLineText(i),1,LinePosToCharIdx(i,SelEnd.X)-1);
  4365. strpcopy(p2,EOL+s);
  4366. end;
  4367. OK:=WinClipboardSupported;
  4368. if OK then
  4369. begin
  4370. OK:=SetTextWinClipBoardData(p,strlen(p));
  4371. end;
  4372. ClipCopyWin:=OK;
  4373. Freemem(p,PCLength);
  4374. UnLock;
  4375. end;
  4376. {$endif WinClipSupported}
  4377. function TCustomCodeEditor.ClipCopy: Boolean;
  4378. var OK: boolean;
  4379. begin
  4380. Lock;
  4381. {AddGroupedAction(eaCopy);
  4382. can we undo a copy ??
  4383. maybe as an Undo Paste in Clipboard !! }
  4384. OK:=Clipboard<>nil;
  4385. if OK then OK:=Clipboard^.InsertFrom(@Self);
  4386. ClipCopy:=OK;
  4387. UnLock;
  4388. end;
  4389. procedure TCustomCodeEditor.ClipCut;
  4390. begin
  4391. if IsReadOnly then Exit;
  4392. Lock;
  4393. AddGroupedAction(eaCut);
  4394. DontConsiderShiftState:=true;
  4395. if Clipboard<>nil then
  4396. if Clipboard^.InsertFrom(@Self) then
  4397. begin
  4398. if not IsClipBoard then
  4399. DelSelect;
  4400. SetModified(true);
  4401. end;
  4402. CloseGroupedAction(eaCut);
  4403. UnLock;
  4404. DontConsiderShiftState:=false;
  4405. end;
  4406. procedure TCustomCodeEditor.ClipPaste;
  4407. begin
  4408. if IsReadOnly then Exit;
  4409. DontConsiderShiftState:=true;
  4410. Lock;
  4411. AddGroupedAction(eaPaste);
  4412. if Clipboard<>nil then
  4413. begin
  4414. InsertFrom(Clipboard);
  4415. SetModified(true);
  4416. end;
  4417. CloseGroupedAction(eaPaste);
  4418. UnLock;
  4419. DontConsiderShiftState:=false;
  4420. end;
  4421. procedure TCustomCodeEditor.Undo;
  4422. begin
  4423. NotImplemented; Exit;
  4424. end;
  4425. procedure TCustomCodeEditor.Redo;
  4426. begin
  4427. NotImplemented; Exit;
  4428. end;
  4429. procedure TCustomCodeEditor.GotoLine;
  4430. var
  4431. GotoRec: TGotoLineDialogRec;
  4432. begin
  4433. with GotoRec do
  4434. begin
  4435. LineNo:='1';
  4436. Lines:=GetLineCount;
  4437. if EditorDialog(edGotoLine, @GotoRec) <> cmCancel then
  4438. begin
  4439. SetCurPtr(0,StrToInt(LineNo)-1);
  4440. TrackCursor(true);
  4441. end;
  4442. end;
  4443. end;
  4444. procedure TCustomCodeEditor.Find;
  4445. var
  4446. FindRec: TFindDialogRec;
  4447. DoConf: boolean;
  4448. begin
  4449. with FindRec do
  4450. begin
  4451. Find := FindStr;
  4452. if GetCurrentWord<>'' then
  4453. Find:=GetCurrentWord;
  4454. Options := (FindFlags and ffmOptions) shr ffsOptions;
  4455. Direction := (FindFlags and ffmDirection) shr ffsDirection;
  4456. Scope := (FindFlags and ffmScope) shr ffsScope;
  4457. Origin := (FindFlags and ffmOrigin) shr ffsOrigin;
  4458. DoConf:= (FindFlags and ffPromptOnReplace)<>0;
  4459. if EditorDialog(edFind, @FindRec) <> cmCancel then
  4460. begin
  4461. FindStr := Find;
  4462. FindFlags := (Options shl ffsOptions) or (Direction shl ffsDirection) or
  4463. (Scope shl ffsScope) or (Origin shl ffsOrigin);
  4464. FindFlags := FindFlags and not ffDoReplace;
  4465. if DoConf then
  4466. FindFlags := (FindFlags or ffPromptOnReplace);
  4467. SearchRunCount:=0;
  4468. DoSearchReplace;
  4469. end;
  4470. end;
  4471. end;
  4472. procedure TCustomCodeEditor.Replace;
  4473. var
  4474. ReplaceRec: TReplaceDialogRec;
  4475. Re: word;
  4476. begin
  4477. if IsReadOnly then Exit;
  4478. with ReplaceRec do
  4479. begin
  4480. Find := FindStr;
  4481. if GetCurrentWord<>'' then
  4482. Find:=GetCurrentWord;
  4483. Replace := ReplaceStr;
  4484. Options := (FindFlags and ffmOptions) shr ffsOptions;
  4485. Direction := (FindFlags and ffmDirection) shr ffsDirection;
  4486. Scope := (FindFlags and ffmScope) shr ffsScope;
  4487. Origin := (FindFlags and ffmOrigin) shr ffsOrigin;
  4488. Re:=EditorDialog(edReplace, @ReplaceRec);
  4489. if Re <> cmCancel then
  4490. begin
  4491. FindStr := Find;
  4492. ReplaceStr := Replace;
  4493. FindFlags := (Options shl ffsOptions) or (Direction shl ffsDirection) or
  4494. (Scope shl ffsScope) or (Origin shl ffsOrigin);
  4495. FindFlags := FindFlags or ffDoReplace;
  4496. if Re = cmYes then
  4497. FindFlags := FindFlags or ffReplaceAll;
  4498. SearchRunCount:=0;
  4499. DoSearchReplace;
  4500. end;
  4501. end;
  4502. end;
  4503. procedure TCustomCodeEditor.DoSearchReplace;
  4504. var S: string;
  4505. DX,DY,P,Y,X: sw_integer;
  4506. Count: sw_integer;
  4507. Found,CanExit: boolean;
  4508. SForward,DoReplace,DoReplaceAll: boolean;
  4509. LeftOK,RightOK: boolean;
  4510. FoundCount: sw_integer;
  4511. A,B: TPoint;
  4512. AreaStart,AreaEnd: TPoint;
  4513. CanReplace,Confirm: boolean;
  4514. Re: word;
  4515. IFindStr : string;
  4516. BT : BTable;
  4517. function ContainsText(const SubS:string;var S: string; Start: Sw_word): Sw_integer;
  4518. var
  4519. P: Sw_Integer;
  4520. begin
  4521. if Start<=0 then
  4522. P:=0
  4523. else
  4524. begin
  4525. if SForward then
  4526. begin
  4527. if Start>length(s) then
  4528. P:=0
  4529. else if FindFlags and ffCaseSensitive<>0 then
  4530. P:=BMFScan(S[Start],length(s)+1-Start,FindStr,Bt)+1
  4531. else
  4532. P:=BMFIScan(S[Start],length(s)+1-Start,IFindStr,Bt)+1;
  4533. if P>0 then
  4534. Inc(P,Start-1);
  4535. end
  4536. else
  4537. begin
  4538. if start>length(s) then
  4539. start:=length(s);
  4540. if FindFlags and ffCaseSensitive<>0 then
  4541. P:=BMBScan(S[1],Start,FindStr,Bt)+1
  4542. else
  4543. P:=BMBIScan(S[1],Start,IFindStr,Bt)+1;
  4544. end;
  4545. end;
  4546. ContainsText:=P;
  4547. end;
  4548. function InArea(X,Y: sw_integer): boolean;
  4549. begin
  4550. InArea:=((AreaStart.Y=Y) and (AreaStart.X<=X)) or
  4551. ((AreaStart.Y<Y) and (Y<AreaEnd.Y)) or
  4552. ((AreaEnd.Y=Y) and (X<=AreaEnd.X));
  4553. end;
  4554. var CurDY: sw_integer;
  4555. begin
  4556. Inc(SearchRunCount);
  4557. SForward:=(FindFlags and ffmDirection)=ffForward;
  4558. DoReplace:=(FindFlags and ffDoReplace)<>0;
  4559. Confirm:=(FindFlags and ffPromptOnReplace)<>0;
  4560. DoReplaceAll:=(FindFlags and ffReplaceAll)<>0;
  4561. Count:=GetLineCount; FoundCount:=0;
  4562. if SForward then
  4563. DY:=1
  4564. else
  4565. DY:=-1;
  4566. DX:=DY;
  4567. if (FindFlags and ffmScope)=ffGlobal then
  4568. begin
  4569. AreaStart.X:=0;
  4570. AreaStart.Y:=0;
  4571. AreaEnd.X:=length(GetDisplayText(Count-1));
  4572. AreaEnd.Y:=Count-1;
  4573. end
  4574. else
  4575. begin
  4576. AreaStart:=SelStart;
  4577. AreaEnd:=SelEnd;
  4578. end;
  4579. X:=CurPos.X-DX;
  4580. Y:=CurPos.Y;;
  4581. if SearchRunCount=1 then
  4582. if (FindFlags and ffmOrigin)=ffEntireScope then
  4583. if SForward then
  4584. begin
  4585. X:=AreaStart.X-1;
  4586. Y:=AreaStart.Y;
  4587. end
  4588. else
  4589. begin
  4590. X:=AreaEnd.X+1;
  4591. Y:=AreaEnd.Y;
  4592. end;
  4593. if FindFlags and ffCaseSensitive<>0 then
  4594. begin
  4595. if SForward then
  4596. BMFMakeTable(FindStr,bt)
  4597. else
  4598. BMBMakeTable(FindStr,bt);
  4599. end
  4600. else
  4601. begin
  4602. IFindStr:=Upper(FindStr);
  4603. if SForward then
  4604. BMFMakeTable(IFindStr,bt)
  4605. else
  4606. BMBMakeTable(IFindStr,bt);
  4607. end;
  4608. inc(X,DX);
  4609. CanExit:=false;
  4610. if (DoReplace=false) or ((Confirm=false) and (Owner<>nil)) then
  4611. Owner^.Lock;
  4612. if InArea(X,Y) then
  4613. repeat
  4614. CurDY:=DY;
  4615. S:=GetDisplayText(Y);
  4616. P:=ContainsText(FindStr,S,X+1);
  4617. Found:=P<>0;
  4618. if Found then
  4619. begin
  4620. A.X:=P-1;
  4621. A.Y:=Y;
  4622. B.Y:=Y;
  4623. B.X:=A.X+length(FindStr);
  4624. end;
  4625. Found:=Found and InArea(A.X,A.Y);
  4626. if Found and ((FindFlags and ffWholeWordsOnly)<>0) then
  4627. begin
  4628. LeftOK:=(A.X<=0) or (not( (S[A.X] in AlphaChars) or (S[A.X] in NumberChars) ));
  4629. RightOK:=(B.X>=length(S)) or (not( (S[B.X+1] in AlphaChars) or (S[B.X+1] in NumberChars) ));
  4630. Found:=LeftOK and RightOK;
  4631. if Found=false then
  4632. begin
  4633. CurDY:=0;
  4634. X:=B.X+1;
  4635. end;
  4636. end;
  4637. if Found then
  4638. Inc(FoundCount);
  4639. if Found then
  4640. begin
  4641. Lock;
  4642. if SForward then
  4643. SetCurPtr(B.X,B.Y)
  4644. else
  4645. SetCurPtr(A.X,A.Y);
  4646. TrackCursor(true);
  4647. SetHighlight(A,B);
  4648. UnLock;
  4649. CurDY:=0;
  4650. if (DoReplace=false) then
  4651. begin
  4652. CanExit:=true;
  4653. If SForward then
  4654. begin
  4655. X:=B.X;
  4656. Y:=B.Y;
  4657. end
  4658. else
  4659. begin
  4660. X:=A.X;
  4661. Y:=A.Y;
  4662. end;
  4663. end
  4664. else
  4665. begin
  4666. if Confirm=false then CanReplace:=true else
  4667. begin
  4668. Re:=EditorDialog(edReplacePrompt,@CurPos);
  4669. case Re of
  4670. cmYes :
  4671. CanReplace:=true;
  4672. cmNo :
  4673. CanReplace:=false;
  4674. else {cmCancel}
  4675. begin
  4676. CanReplace:=false;
  4677. CanExit:=true;
  4678. end;
  4679. end;
  4680. end;
  4681. if CanReplace then
  4682. begin
  4683. Lock;
  4684. SetSelection(A,B);
  4685. DelSelect;
  4686. InsertText(ReplaceStr);
  4687. if SForward then
  4688. begin
  4689. X:=CurPos.X;
  4690. Y:=CurPos.Y;
  4691. end
  4692. else
  4693. begin
  4694. X:=A.X;
  4695. Y:=A.Y;
  4696. end;
  4697. UnLock;
  4698. end
  4699. else
  4700. begin
  4701. If SForward then
  4702. begin
  4703. X:=B.X;
  4704. Y:=B.Y;
  4705. end
  4706. else
  4707. begin
  4708. X:=A.X;
  4709. Y:=A.Y;
  4710. end;
  4711. end;
  4712. if (DoReplaceAll=false) then
  4713. CanExit:=true;
  4714. end;
  4715. end;
  4716. if (CanExit=false) and (CurDY<>0) then
  4717. begin
  4718. inc(Y,CurDY);
  4719. if SForward then
  4720. X:=0
  4721. else
  4722. X:=254;
  4723. CanExit:=(Y>=Count) or (Y<0);
  4724. end;
  4725. if not CanExit then
  4726. CanExit:=not InArea(X,Y);
  4727. until CanExit;
  4728. if (FoundCount=0) or (DoReplace) then
  4729. SetHighlight(CurPos,CurPos);
  4730. if (DoReplace=false) or ((Confirm=false) and (Owner<>nil)) then
  4731. Owner^.UnLock;
  4732. {if (DoReplace=false) or (Confirm=false) then
  4733. UnLock;}
  4734. if (FoundCount=0) then
  4735. EditorDialog(edSearchFailed,nil);
  4736. if (FindFlags and ffmScope)=ffSelectedText then
  4737. { restore selection PM }
  4738. begin
  4739. SetSelection(AreaStart,AreaEnd);
  4740. end;
  4741. end;
  4742. function TCustomCodeEditor.GetInsertMode: boolean;
  4743. begin
  4744. GetInsertMode:=(GetFlags and efInsertMode)<>0;
  4745. end;
  4746. procedure TCustomCodeEditor.SetInsertMode(InsertMode: boolean);
  4747. begin
  4748. if InsertMode then
  4749. SetFlags(GetFlags or efInsertMode)
  4750. else
  4751. SetFlags(GetFlags and (not efInsertMode));
  4752. DrawCursor;
  4753. end;
  4754. { there is a problem with ShiftDel here
  4755. because GetShitState tells to extend the
  4756. selection which gives wrong results (PM) }
  4757. function TCustomCodeEditor.ShouldExtend: boolean;
  4758. var ShiftInEvent: boolean;
  4759. begin
  4760. ShiftInEvent:=false;
  4761. if Assigned(CurEvent) then
  4762. if CurEvent^.What=evKeyDown then
  4763. ShiftInEvent:=((CurEvent^.KeyShift and kbShift)<>0);
  4764. ShouldExtend:=ShiftInEvent and
  4765. not DontConsiderShiftState;
  4766. end;
  4767. procedure TCustomCodeEditor.SetCurPtr(X,Y: sw_integer);
  4768. var OldPos{,OldSEnd,OldSStart}: TPoint;
  4769. Extended: boolean;
  4770. begin
  4771. Lock;
  4772. X:=Max(0,Min(MaxLineLength+1,X));
  4773. Y:=Max(0,Min(GetLineCount-1,Y));
  4774. OldPos:=CurPos;
  4775. { OldSEnd:=SelEnd;
  4776. OldSStart:=SelStart;}
  4777. CurPos.X:=X;
  4778. CurPos.Y:=Y;
  4779. TrackCursor(false);
  4780. if (NoSelect=false) and (ShouldExtend) then
  4781. begin
  4782. CheckSels;
  4783. Extended:=false;
  4784. if PointOfs(OldPos)=PointOfs(SelStart) then
  4785. begin SetSelection(CurPos,SelEnd); Extended:=true; end;
  4786. CheckSels;
  4787. if Extended=false then
  4788. if PointOfs(OldPos)=PointOfs(SelEnd) then
  4789. begin
  4790. if ValidBlock=false then
  4791. SetSelection(CurPos,CurPos);
  4792. SetSelection(SelStart,CurPos); Extended:=true;
  4793. end;
  4794. CheckSels;
  4795. if (Extended=false) then
  4796. if PointOfs(OldPos)<=PointOfs(CurPos)
  4797. then begin SetSelection(OldPos,CurPos); Extended:=true; end
  4798. else begin SetSelection(CurPos,OldPos); Extended:=true; end;
  4799. DrawView;
  4800. end else
  4801. if not IsFlagSet(efPersistentBlocks) then
  4802. begin HideSelect; DrawView; end;
  4803. { if PointOfs(SelStart)=PointOfs(SelEnd) then
  4804. SetSelection(CurPos,CurPos);}
  4805. if (GetFlags and (efHighlightColumn+efHighlightRow))<>0 then
  4806. DrawView;
  4807. if ((CurPos.X<>OldPos.X) or (CurPos.Y<>OldPos.Y)) and
  4808. ((Highlight.A.X<>HighLight.B.X) or (Highlight.A.Y<>HighLight.B.Y)) then
  4809. HideHighlight;
  4810. if (OldPos.Y<>CurPos.Y) and (0<=OldPos.Y) and (OldPos.Y<GetLineCount) then
  4811. SetLineText(OldPos.Y,RTrim(GetLineText(OldPos.Y),not IsFlagSet(efUseTabCharacters)));
  4812. if ((CurPos.X<>OldPos.X) or (CurPos.Y<>OldPos.Y)) and (GetErrorMessage<>'') then
  4813. SetErrorMessage('');
  4814. { if ((CurPos.X<>OldPos.X) or (CurPos.Y<>OldPos.Y)) and (HighlightRow<>-1) then
  4815. SetHighlightRow(-1);}
  4816. if ((CurPos.X<>OldPos.X) or (CurPos.Y<>OldPos.Y)) then
  4817. AddAction(eaMoveCursor,OldPos,CurPos,'');
  4818. if ((CurPos.X<>OldPos.X) or (CurPos.Y<>OldPos.Y)) then
  4819. PositionChanged;{UpdateIndicator;}
  4820. UnLock;
  4821. end;
  4822. procedure TCustomCodeEditor.CheckSels;
  4823. begin
  4824. if (SelStart.Y>SelEnd.Y) or
  4825. ( (SelStart.Y=SelEnd.Y) and (SelStart.X>SelEnd.X) ) then
  4826. SetSelection(SelEnd,SelStart);
  4827. end;
  4828. procedure TCustomCodeEditor.CodeCompleteApply;
  4829. var S: string;
  4830. I: integer;
  4831. begin
  4832. Lock;
  4833. { here should be some kind or "mark" or "break" inserted in the Undo
  4834. information, so activating it "undoes" only the completition first and
  4835. doesn't delete the complete word at once... - Gabor }
  4836. S:=GetCodeCompleteFrag;
  4837. SetCurPtr(CurPos.X-length(S),CurPos.Y);
  4838. for I:=1 to length(S) do
  4839. DelChar;
  4840. S:=GetCodeCompleteWord;
  4841. for I:=1 to length(S) do
  4842. AddChar(S[I]);
  4843. UnLock;
  4844. SetCompleteState(csInactive);
  4845. end;
  4846. procedure TCustomCodeEditor.CodeCompleteCancel;
  4847. begin
  4848. SetCompleteState(csDenied);
  4849. end;
  4850. procedure TCustomCodeEditor.CodeCompleteCheck;
  4851. var Line: string;
  4852. X: sw_integer;
  4853. CurWord,NewWord: string;
  4854. begin
  4855. SetCodeCompleteFrag('');
  4856. if (not IsFlagSet(efCodeComplete)) or (IsReadOnly=true) then Exit;
  4857. Lock;
  4858. Line:=GetDisplayText(CurPos.Y);
  4859. X:=CurPos.X; CurWord:='';
  4860. if X<=length(Line) then
  4861. while (X>0) and (Line[X] in (NumberChars+AlphaChars)) do
  4862. begin
  4863. CurWord:=Line[X]+CurWord;
  4864. Dec(X);
  4865. end;
  4866. if (length(CurWord)>=CodeCompleteMinLen) and CompleteCodeWord(CurWord,NewWord) then
  4867. begin
  4868. SetCodeCompleteFrag(CurWord);
  4869. SetCodeCompleteWord(NewWord);
  4870. end
  4871. else
  4872. ClearCodeCompleteWord;
  4873. UnLock;
  4874. end;
  4875. function TCustomCodeEditor.GetCodeCompleteFrag: string;
  4876. begin
  4877. { Abstract }
  4878. GetCodeCompleteFrag:='';
  4879. end;
  4880. procedure TCustomCodeEditor.SetCodeCompleteFrag(const S: string);
  4881. begin
  4882. { Abstract }
  4883. end;
  4884. procedure TCustomCodeEditor.DrawLines(FirstLine: sw_integer);
  4885. begin
  4886. if FirstLine>=(Delta.Y+Size.Y) then Exit; { falls outside of the screen }
  4887. DrawView;
  4888. end;
  4889. procedure TCustomCodeEditor.HideHighlight;
  4890. begin
  4891. SetHighlight(CurPos,CurPos);
  4892. end;
  4893. procedure TCustomCodeEditor.GetSelectionArea(var StartP,EndP: TPoint);
  4894. begin
  4895. StartP:=SelStart; EndP:=SelEnd;
  4896. if EndP.X=0 then
  4897. begin
  4898. Dec(EndP.Y);
  4899. EndP.X:=length(GetDisplayText(EndP.Y))-1;
  4900. end
  4901. else
  4902. Dec(EndP.X);
  4903. end;
  4904. function TCustomCodeEditor.ValidBlock: boolean;
  4905. begin
  4906. ValidBlock:=(SelStart.X<>SelEnd.X) or (SelStart.Y<>SelEnd.Y);
  4907. end;
  4908. procedure TCustomCodeEditor.SetSelection(A, B: TPoint);
  4909. var WV: boolean;
  4910. OS,OE: TPoint;
  4911. begin
  4912. WV:=ValidBlock;
  4913. OS:=SelStart; OE:=SelEnd;
  4914. SelStart:=A; SelEnd:=B;
  4915. if (WV=false) and (ValidBlock=false) then { do nothing } else
  4916. if (OS.X<>SelStart.X) or (OS.Y<>SelStart.Y) or
  4917. (OE.X<>SelEnd.X) or (OE.Y<>SelEnd.Y) then
  4918. SelectionChanged;
  4919. end;
  4920. procedure TCustomCodeEditor.SetHighlight(A, B: TPoint);
  4921. begin
  4922. Highlight.A:=A; Highlight.B:=B;
  4923. HighlightChanged;
  4924. end;
  4925. {procedure TCustomCodeEditor.SetHighlightRow(Row: sw_integer);
  4926. begin
  4927. HighlightRow:=Row;
  4928. DrawView;
  4929. end;}
  4930. {procedure TCodeEditor.SetDebuggerRow(Row: sw_integer);
  4931. begin
  4932. DebuggerRow:=Row;
  4933. DrawView;
  4934. end;}
  4935. procedure TCustomCodeEditor.SelectAll(Enable: boolean);
  4936. var A,B: TPoint;
  4937. begin
  4938. if (Enable=false) or (GetLineCount=0) then
  4939. begin A:=CurPos; B:=CurPos end
  4940. else
  4941. begin
  4942. A.X:=0; A.Y:=0;
  4943. { B.Y:=GetLineCount-1;
  4944. B.X:=length(GetLineText(B.Y));}
  4945. B.Y:=GetLineCount; B.X:=0;
  4946. end;
  4947. SetSelection(A,B);
  4948. DrawView;
  4949. end;
  4950. procedure TCustomCodeEditor.SelectionChanged;
  4951. var Enable,CanPaste: boolean;
  4952. begin
  4953. if GetLineCount=0 then
  4954. begin
  4955. SelStart.X:=0; SelStart.Y:=0; SelEnd:=SelStart;
  4956. end
  4957. else
  4958. if SelEnd.Y>GetLineCount-1 then
  4959. if (SelEnd.Y<>GetLineCount) or (SelEnd.X<>0) then
  4960. begin
  4961. SelEnd.Y:=GetLineCount-1;
  4962. SelEnd.X:=length(GetDisplayText(SelEnd.Y));
  4963. end;
  4964. Enable:=((SelStart.X<>SelEnd.X) or (SelStart.Y<>SelEnd.Y)) and (Clipboard<>nil);
  4965. SetCmdState(ToClipCmds,Enable and (Clipboard<>@Self));
  4966. SetCmdState(NulClipCmds,Enable);
  4967. CanPaste:=(Clipboard<>nil) and ((Clipboard^.SelStart.X<>Clipboard^.SelEnd.X) or
  4968. (Clipboard^.SelStart.Y<>Clipboard^.SelEnd.Y));
  4969. SetCmdState(FromClipCmds,CanPaste and (Clipboard<>@Self));
  4970. {$ifdef WinClipSupported}
  4971. SetCmdState(FromWinClipCmds,GetTextWinClipboardSize>0);
  4972. {$endif WinClipSupported}
  4973. SetCmdState(UndoCmd,(GetUndoActionCount>0));
  4974. SetCmdState(RedoCmd,(GetRedoActionCount>0));
  4975. Message(Application,evBroadcast,cmCommandSetChanged,nil);
  4976. DrawView;
  4977. end;
  4978. procedure TCustomCodeEditor.HighlightChanged;
  4979. begin
  4980. DrawView;
  4981. end;
  4982. procedure TCustomCodeEditor.SetState(AState: Word; Enable: Boolean);
  4983. procedure ShowSBar(SBar: PScrollBar);
  4984. begin
  4985. if Assigned(SBar) and (SBar^.GetState(sfVisible)=false) then
  4986. SBar^.Show;
  4987. end;
  4988. begin
  4989. inherited SetState(AState,Enable);
  4990. if AlwaysShowScrollBars then
  4991. begin
  4992. ShowSBar(HScrollBar);
  4993. ShowSBar(VScrollBar);
  4994. end;
  4995. if (AState and (sfActive+sfSelected+sfFocused))<>0 then
  4996. begin
  4997. SelectionChanged;
  4998. if ((State and sfFocused)=0) and (GetCompleteState=csOffering) then
  4999. ClearCodeCompleteWord;
  5000. end;
  5001. end;
  5002. function TCustomCodeEditor.GetPalette: PPalette;
  5003. const P: string[length(CEditor)] = CEditor;
  5004. begin
  5005. GetPalette:=@P;
  5006. end;
  5007. function TCustomCodeEditorCore.LoadFromStream(Editor: PCustomCodeEditor; Stream: PStream): boolean;
  5008. var S: string;
  5009. AllLinesComplete,LineComplete,OK: boolean;
  5010. begin
  5011. DeleteAllLines;
  5012. ChangedLine:=-1;
  5013. AllLinesComplete:=true;
  5014. OK:=(Stream^.Status=stOK);
  5015. if eofstream(Stream) then
  5016. AddLine('')
  5017. else
  5018. while OK and (eofstream(Stream)=false) and (GetLineCount<MaxLineCount) do
  5019. begin
  5020. ReadlnFromStream(Stream,S,LineComplete);
  5021. AllLinesComplete:=AllLinesComplete and LineComplete;
  5022. OK:=OK and (Stream^.Status=stOK);
  5023. if OK then AddLine(S);
  5024. if not LineComplete and (ChangedLine=-1) then
  5025. ChangedLine:=GetLineCount;
  5026. end;
  5027. LimitsChanged;
  5028. if not AllLinesComplete then
  5029. SetModified(true);
  5030. if (GetLineCount=MaxLineCount) and not eofstream(stream) then
  5031. EditorDialog(edTooManyLines,nil);
  5032. LoadFromStream:=OK;
  5033. end;
  5034. function TCustomCodeEditorCore.SaveAreaToStream(Editor: PCustomCodeEditor; Stream: PStream; StartP,EndP: TPoint): boolean;
  5035. var S: string;
  5036. OK: boolean;
  5037. Line: Sw_integer;
  5038. P: PCustomLine;
  5039. begin
  5040. if EndP.X=0 then
  5041. begin
  5042. if EndP.Y>0 then
  5043. begin
  5044. EndP.X:=length(GetDisplayText(EndP.Y));
  5045. end
  5046. else
  5047. EndP.X:=0;
  5048. end
  5049. else
  5050. Dec(EndP.X);
  5051. OK:=(Stream^.Status=stOK); Line:=StartP.Y;
  5052. while OK and (Line<=EndP.Y) and (Line<GetLineCount) do
  5053. begin
  5054. P:=GetLine(Line);
  5055. S:=P^.GetText;
  5056. { Remove all traling spaces PM }
  5057. if not Editor^.IsFlagSet(efKeepTrailingSpaces) then
  5058. While (Length(S)>0) and (S[Length(S)]=' ') do
  5059. Dec(S[0]);
  5060. { if FlagSet(efUseTabCharacters) then
  5061. S:=CompressUsingTabs(S,TabSize);
  5062. }
  5063. if Line=EndP.Y then S:=copy(S,1,LinePosToCharIdx(Line,EndP.X));
  5064. if Line=StartP.Y then S:=copy(S,LinePosToCharIdx(Line,StartP.X),High(S));
  5065. Stream^.Write(S[1],length(S));
  5066. if Line<EndP.Y then
  5067. Stream^.Write(EOL[1],length(EOL));
  5068. Inc(Line);
  5069. OK:=OK and (Stream^.Status=stOK);
  5070. end;
  5071. SaveAreaToStream:=OK;
  5072. end;
  5073. {$ifdef Undo}
  5074. constructor TEditorAction.init(act:byte; StartP,EndP:TPoint;Txt:String);
  5075. begin
  5076. Action:=act;
  5077. StartPos:=StartP;
  5078. EndPos:=EndP;
  5079. Text:=NewStr(txt);
  5080. ActionCount:=0;
  5081. end;
  5082. constructor TEditorAction.init_group(act:byte);
  5083. begin
  5084. Action:=act;
  5085. ActionCount:=0;
  5086. end;
  5087. function TEditorAction.Is_grouped_action : boolean;
  5088. begin
  5089. Is_grouped_action:=Action in [eaCut,eaPaste,eaPasteWin,eaClear];
  5090. end;
  5091. destructor TEditorAction.done;
  5092. begin
  5093. DisposeStr(Text);
  5094. end;
  5095. {$else}
  5096. procedure TEditorActionCollection.FreeItem(Item: Pointer);
  5097. begin
  5098. if assigned(Item) then
  5099. freemem(Item,Sizeof(TEditorAction));
  5100. end;
  5101. {$endif Undo}
  5102. function TEditorActionCollection.At(Idx : sw_integer) : PEditorAction;
  5103. begin
  5104. At:=PEditorAction(Inherited At(Idx));
  5105. end;
  5106. function CreateFindDialog: PDialog;
  5107. var R,R1,R2: TRect;
  5108. D: PDialog;
  5109. IL1: PInputLine;
  5110. Control : PView;
  5111. CB1: PCheckBoxes;
  5112. RB1,RB2,RB3: PRadioButtons;
  5113. begin
  5114. R.Assign(0,0,56,15);
  5115. New(D, Init(R, dialog_find));
  5116. with D^ do
  5117. begin
  5118. Options:=Options or ofCentered;
  5119. GetExtent(R); R.Grow(-3,-2);
  5120. R1.Copy(R); R1.B.X:=17; R1.B.Y:=R1.A.Y+1;
  5121. R2.Copy(R); R2.B.X:=R2.B.X-3;R2.A.X:=17; R2.B.Y:=R2.A.Y+1;
  5122. New(IL1, Init(R2, FindStrSize));
  5123. IL1^.Data^:=FindStr;
  5124. Insert(IL1);
  5125. Insert(New(PLabel, Init(R1, label_find_texttofind, IL1)));
  5126. R1.Assign(R2.B.X, R2.A.Y, R2.B.X+3, R2.B.Y);
  5127. Control := New(PHistory, Init(R1, IL1, TextFindId));
  5128. Insert(Control);
  5129. R1.Copy(R); Inc(R1.A.Y,2); R1.B.Y:=R1.A.Y+1; R1.B.X:=R1.A.X+(R1.B.X-R1.A.X) div 2-1;
  5130. R2.Copy(R1); R2.Move(0,1); R2.B.Y:=R2.A.Y+2;
  5131. New(CB1, Init(R2,
  5132. NewSItem(label_find_casesensitive,
  5133. NewSItem(label_find_wholewordsonly,
  5134. nil))));
  5135. Insert(CB1);
  5136. Insert(New(PLabel, Init(R1, label_find_options, CB1)));
  5137. R1.Copy(R); Inc(R1.A.Y,2); R1.B.Y:=R1.A.Y+1; R1.A.X:=R1.B.X-(R1.B.X-R1.A.X) div 2+1;
  5138. R2.Copy(R1); R2.Move(0,1); R2.B.Y:=R2.A.Y+2;
  5139. New(RB1, Init(R2,
  5140. NewSItem(label_find_forward,
  5141. NewSItem(label_find_backward,
  5142. nil))));
  5143. Insert(RB1);
  5144. Insert(New(PLabel, Init(R1, label_find_direction, RB1)));
  5145. R1.Copy(R); Inc(R1.A.Y,6); R1.B.Y:=R1.A.Y+1; R1.B.X:=R1.A.X+(R1.B.X-R1.A.X) div 2-1;
  5146. R2.Copy(R1); R2.Move(0,1); R2.B.Y:=R2.A.Y+2;
  5147. New(RB2, Init(R2,
  5148. NewSItem(label_find_global,
  5149. NewSItem(label_find_selectedtext,
  5150. nil))));
  5151. Insert(RB2);
  5152. Insert(New(PLabel, Init(R1, label_find_scope, RB2)));
  5153. R1.Copy(R); Inc(R1.A.Y,6); R1.B.Y:=R1.A.Y+1; R1.A.X:=R1.B.X-(R1.B.X-R1.A.X) div 2+1;
  5154. R2.Copy(R1); R2.Move(0,1); R2.B.Y:=R2.A.Y+2;
  5155. New(RB3, Init(R2,
  5156. NewSItem(label_find_fromcursor,
  5157. NewSItem(label_find_entirescope,
  5158. nil))));
  5159. Insert(RB3);
  5160. Insert(New(PLabel, Init(R1, label_find_origin, RB3)));
  5161. GetExtent(R); R.Grow(-13,-1); R.A.Y:=R.B.Y-2; R.B.X:=R.A.X+10;
  5162. Insert(New(PButton, Init(R, btn_OK, cmOK, bfDefault)));
  5163. R.Move(19,0);
  5164. Insert(New(PButton, Init(R, btn_Cancel, cmCancel, bfNormal)));
  5165. end;
  5166. IL1^.Select;
  5167. CreateFindDialog := D;
  5168. end;
  5169. function CreateReplaceDialog: PDialog;
  5170. var R,R1,R2: TRect;
  5171. D: PDialog;
  5172. Control : PView;
  5173. IL1,IL2: PInputLine;
  5174. CB1: PCheckBoxes;
  5175. RB1,RB2,RB3: PRadioButtons;
  5176. begin
  5177. R.Assign(0,0,56,18);
  5178. New(D, Init(R, dialog_replace));
  5179. with D^ do
  5180. begin
  5181. Options:=Options or ofCentered;
  5182. GetExtent(R); R.Grow(-3,-2);
  5183. R1.Copy(R); R1.B.X:=17; R1.B.Y:=R1.A.Y+1;
  5184. R2.Copy(R); R2.B.X:=R2.B.X-3;R2.A.X:=17; R2.B.Y:=R2.A.Y+1;
  5185. New(IL1, Init(R2, FindStrSize));
  5186. IL1^.Data^:=FindStr;
  5187. Insert(IL1);
  5188. Insert(New(PLabel, Init(R1, label_replace_texttofind, IL1)));
  5189. R1.Assign(R2.B.X, R2.A.Y, R2.B.X+3, R2.B.Y);
  5190. Control := New(PHistory, Init(R1, IL1, TextFindId));
  5191. Insert(Control);
  5192. R1.Copy(R); R1.Move(0,2); R1.B.X:=17; R1.B.Y:=R1.A.Y+1;
  5193. R2.Copy(R); R2.Move(0,2);R2.B.X:=R2.B.X-3;
  5194. R2.A.X:=17; R2.B.Y:=R2.A.Y+1;
  5195. New(IL2, Init(R2, FindStrSize));
  5196. IL2^.Data^:=ReplaceStr;
  5197. Insert(IL2);
  5198. Insert(New(PLabel, Init(R1, label_replace_newtext, IL2)));
  5199. R1.Assign(R2.B.X, R2.A.Y, R2.B.X+3, R2.B.Y);
  5200. Control := New(PHistory, Init(R1, IL2, TextReplaceId));
  5201. Insert(Control);
  5202. R1.Copy(R); Inc(R1.A.Y,4); R1.B.Y:=R1.A.Y+1; R1.B.X:=R1.A.X+(R1.B.X-R1.A.X) div 2-1;
  5203. R2.Copy(R1); R2.Move(0,1); R2.B.Y:=R2.A.Y+3;
  5204. New(CB1, Init(R2,
  5205. NewSItem(label_replace_casesensitive,
  5206. NewSItem(label_replace_wholewordsonly,
  5207. NewSItem(label_replace_promptonreplace,
  5208. nil)))));
  5209. Insert(CB1);
  5210. Insert(New(PLabel, Init(R1, label_replace_options, CB1)));
  5211. R1.Copy(R); Inc(R1.A.Y,4); R1.B.Y:=R1.A.Y+1; R1.A.X:=R1.B.X-(R1.B.X-R1.A.X) div 2+1;
  5212. R2.Copy(R1); R2.Move(0,1); R2.B.Y:=R2.A.Y+2;
  5213. New(RB1, Init(R2,
  5214. NewSItem(label_replace_forward,
  5215. NewSItem(label_replace_backward,
  5216. nil))));
  5217. Insert(RB1);
  5218. Insert(New(PLabel, Init(R1, label_replace_direction, RB1)));
  5219. R1.Copy(R); Inc(R1.A.Y,9); R1.B.Y:=R1.A.Y+1; R1.B.X:=R1.A.X+(R1.B.X-R1.A.X) div 2-1;
  5220. R2.Copy(R1); R2.Move(0,1); R2.B.Y:=R2.A.Y+2;
  5221. New(RB2, Init(R2,
  5222. NewSItem(label_replace_global,
  5223. NewSItem(label_replace_selectedtext,
  5224. nil))));
  5225. Insert(RB2);
  5226. Insert(New(PLabel, Init(R1, label_replace_scope, RB2)));
  5227. R1.Copy(R); Inc(R1.A.Y,9); R1.B.Y:=R1.A.Y+1; R1.A.X:=R1.B.X-(R1.B.X-R1.A.X) div 2+1;
  5228. R2.Copy(R1); R2.Move(0,1); R2.B.Y:=R2.A.Y+2;
  5229. New(RB3, Init(R2,
  5230. NewSItem(label_replace_fromcursor,
  5231. NewSItem(label_replace_entirescope,
  5232. nil))));
  5233. Insert(RB3);
  5234. Insert(New(PLabel, Init(R1, label_replace_origin, RB3)));
  5235. GetExtent(R); R.Grow(-13,-1); R.A.Y:=R.B.Y-2; R.B.X:=R.A.X+10; R.Move(-10,0);
  5236. Insert(New(PButton, Init(R, btn_OK, cmOK, bfDefault)));
  5237. R.Move(11,0); R.B.X:=R.A.X+14;
  5238. Insert(New(PButton, Init(R, btn_replace_changeall, cmYes, bfNormal)));
  5239. R.Move(15,0); R.B.X:=R.A.X+10;
  5240. Insert(New(PButton, Init(R, btn_Cancel, cmCancel, bfNormal)));
  5241. end;
  5242. IL1^.Select;
  5243. CreateReplaceDialog := D;
  5244. end;
  5245. function CreateGotoLineDialog(Info: pointer): PDialog;
  5246. var D: PDialog;
  5247. R,R1,R2: TRect;
  5248. Control : PView;
  5249. IL: PInputLine;
  5250. begin
  5251. R.Assign(0,0,40,7);
  5252. New(D, Init(R, dialog_gotoline));
  5253. with D^ do
  5254. begin
  5255. Options:=Options or ofCentered;
  5256. GetExtent(R); R.Grow(-3,-2); R.B.Y:=R.A.Y+1;
  5257. R1.Copy(R); R1.B.X:=27; R2.Copy(R);
  5258. R2.B.X:=R2.B.X-3;R2.A.X:=27;
  5259. New(IL, Init(R2,5));
  5260. with TGotoLineDialogRec(Info^) do
  5261. IL^.SetValidator(New(PRangeValidator, Init(1, Lines)));
  5262. Insert(IL);
  5263. Insert(New(PLabel, Init(R1, label_gotoline_linenumber, IL)));
  5264. R1.Assign(R2.B.X, R2.A.Y, R2.B.X+3, R2.B.Y);
  5265. Control := New(PHistory, Init(R1, IL, GotoId));
  5266. Insert(Control);
  5267. GetExtent(R); R.Grow(-8,-1); R.A.Y:=R.B.Y-2; R.B.X:=R.A.X+10;
  5268. Insert(New(PButton, Init(R, btn_OK, cmOK, bfDefault)));
  5269. R.Move(15,0);
  5270. Insert(New(PButton, Init(R, btn_Cancel, cmCancel, bfNormal)));
  5271. end;
  5272. IL^.Select;
  5273. CreateGotoLineDialog:=D;
  5274. end;
  5275. function StdEditorDialog(Dialog: Integer; Info: Pointer): Word;
  5276. var
  5277. R: TRect;
  5278. T: TPoint;
  5279. Re: word;
  5280. Name: string;
  5281. DriveNumber : byte;
  5282. StoreDir,StoreDir2 : DirStr;
  5283. Title,DefExt: string;
  5284. AskOW: boolean;
  5285. begin
  5286. case Dialog of
  5287. edOutOfMemory:
  5288. StdEditorDialog := MessageBox(msg_notenoughmemoryforthisoperation,
  5289. nil, mfInsertInApp+ mfError + mfOkButton);
  5290. edReadError:
  5291. StdEditorDialog := MessageBox(msg_errorreadingfile,
  5292. @Info, mfInsertInApp+ mfError + mfOkButton);
  5293. edWriteError:
  5294. StdEditorDialog := MessageBox(msg_errorwritingfile,
  5295. @Info, mfInsertInApp+ mfError + mfOkButton);
  5296. edSaveError:
  5297. StdEditorDialog := MessageBox(msg_errorsavingfile,
  5298. @Info, mfInsertInApp+ mfError + mfOkButton);
  5299. edCreateError:
  5300. StdEditorDialog := MessageBox(msg_errorcreatingfile,
  5301. @Info, mfInsertInApp+ mfError + mfOkButton);
  5302. edSaveModify:
  5303. StdEditorDialog := MessageBox(msg_filehasbeenmodifiedsave,
  5304. @Info, mfInsertInApp+ mfInformation + mfYesNoCancel);
  5305. edSaveUntitled:
  5306. StdEditorDialog := MessageBox(msg_saveuntitledfile,
  5307. nil, mfInsertInApp+ mfInformation + mfYesNoCancel);
  5308. edChangedOnloading:
  5309. StdEditorDialog := MessageBox(msg_filehadtoolonglines,
  5310. Info, mfInsertInApp+ mfOKButton + mfInformation);
  5311. edFileOnDiskChanged:
  5312. StdEditorDialog := MessageBox(msg_filewasmodified,
  5313. @info, mfInsertInApp+ mfInformation + mfYesNoCancel);
  5314. edSaveAs,edWriteBlock,edReadBlock:
  5315. begin
  5316. Name:=PString(Info)^;
  5317. GetDir(0,StoreDir);
  5318. DriveNumber:=0;
  5319. if (Length(FileDir)>1) and (FileDir[2]=':') then
  5320. begin
  5321. { does not assume that lowercase are greater then uppercase ! }
  5322. if (FileDir[1]>='a') and (FileDir[1]<='z') then
  5323. DriveNumber:=Ord(FileDir[1])-ord('a')+1
  5324. else
  5325. DriveNumber:=Ord(FileDir[1])-ord('A')+1;
  5326. GetDir(DriveNumber,StoreDir2);
  5327. {$ifndef FPC}
  5328. ChDir(Copy(FileDir,1,2));
  5329. { this sets InOutRes in win32 PM }
  5330. { is this bad? What about an EatIO? Gabor }
  5331. {$endif not FPC}
  5332. end;
  5333. if FileDir<>'' then
  5334. ChDir(TrimEndSlash(FileDir));
  5335. case Dialog of
  5336. edSaveAs :
  5337. begin
  5338. Title:=dialog_savefileas;
  5339. DefExt:='*'+DefaultSaveExt;
  5340. end;
  5341. edWriteBlock :
  5342. begin
  5343. Title:=dialog_writeblocktofile;
  5344. DefExt:='';
  5345. end;
  5346. edReadBlock :
  5347. begin
  5348. Title:=dialog_readblockfromfile;
  5349. DefExt:='';
  5350. end;
  5351. else begin Title:='???'; DefExt:=''; end;
  5352. end;
  5353. Re:=Application^.ExecuteDialog(New(PFileDialog, Init(DefExt,
  5354. Title, label_name, fdOkButton, FileId)), @Name);
  5355. case Dialog of
  5356. edSaveAs :
  5357. begin
  5358. if ExtOf(Name)='' then
  5359. Name:=Name+DefaultSaveExt;
  5360. AskOW:=(Name<>PString(Info)^);
  5361. end;
  5362. edWriteBlock :
  5363. begin
  5364. if ExtOf(Name)='' then
  5365. Name:=Name+DefaultSaveExt;
  5366. AskOW:=true;
  5367. end;
  5368. edReadBlock : AskOW:=false;
  5369. else AskOW:=true;
  5370. end;
  5371. if (Re<>cmCancel) and AskOW then
  5372. begin
  5373. FileDir:=DirOf(FExpand(Name));
  5374. if ExistsFile(Name) then
  5375. if EditorDialog(edReplaceFile,@Name)<>cmYes then
  5376. Re:=cmCancel;
  5377. end;
  5378. if DriveNumber<>0 then
  5379. ChDir(StoreDir2);
  5380. {$ifndef FPC}
  5381. if (Length(StoreDir)>1) and (StoreDir[2]=':') then
  5382. ChDir(Copy(StoreDir,1,2));
  5383. {$endif not FPC}
  5384. if StoreDir<>'' then
  5385. ChDir(TrimEndSlash(StoreDir));
  5386. if Re<>cmCancel then
  5387. PString(Info)^:=Name;
  5388. StdEditorDialog := Re;
  5389. end;
  5390. edGotoLine:
  5391. StdEditorDialog :=
  5392. Application^.ExecuteDialog(CreateGotoLineDialog(Info), Info);
  5393. edFind:
  5394. StdEditorDialog :=
  5395. Application^.ExecuteDialog(CreateFindDialog, Info);
  5396. edSearchFailed:
  5397. StdEditorDialog := MessageBox(msg_searchstringnotfound,
  5398. nil, mfInsertInApp+ mfError + mfOkButton);
  5399. edReplace:
  5400. StdEditorDialog :=
  5401. Application^.ExecuteDialog(CreateReplaceDialog, Info);
  5402. edReplacePrompt:
  5403. begin
  5404. { Avoid placing the dialog on the same line as the cursor }
  5405. R.Assign(0, 1, 40, 8);
  5406. R.Move((Desktop^.Size.X - R.B.X) div 2, 0);
  5407. Desktop^.MakeGlobal(R.B, T);
  5408. Inc(T.Y);
  5409. if PPoint(Info)^.Y <= T.Y then
  5410. R.Move(0, Desktop^.Size.Y - R.B.Y - 2);
  5411. StdEditorDialog := MessageBoxRect(R, msg_replacethisoccourence,
  5412. nil, mfInsertInApp+ mfYesNoCancel + mfInformation);
  5413. end;
  5414. edReplaceFile :
  5415. StdEditorDialog :=
  5416. MessageBox(msg_fileexistsoverwrite,@Info,mfInsertInApp+mfConfirmation+
  5417. mfYesButton+mfNoButton);
  5418. end;
  5419. end;
  5420. procedure RegisterWEditor;
  5421. begin
  5422. {$ifndef NOOBJREG}
  5423. {$endif}
  5424. end;
  5425. END.
  5426. {
  5427. $Log$
  5428. Revision 1.2 2000-08-22 09:41:41 pierre
  5429. * first big merge from fixes branch
  5430. Revision 1.1.2.4 2000/08/15 03:40:54 peter
  5431. [*] no more fatal exits when the IDE can't find the error file (containing
  5432. the redirected assembler/linker output) after compilation
  5433. [*] hidden windows are now added always at the end of the Window List
  5434. [*] TINIFile parsed entries encapsulated in string delimiters incorrectly
  5435. [*] selection was incorrectly adjusted when typing in overwrite mode
  5436. [*] the line wasn't expanded when it's end was reached in overw. mode
  5437. [*] the IDE now tries to locate source files also in the user specified
  5438. unit dirs (for ex. as a response to 'Open at cursor' (Ctrl+Enter) )
  5439. [*] 'Open at cursor' is now aware of the extension (if specified)
  5440. Revision 1.1.2.3 2000/07/20 11:02:16 michael
  5441. + Fixes from gabor. See fixes.txt
  5442. Revision 1.1.2.2 2000/07/18 05:50:22 michael
  5443. + Merged Gabors fixes
  5444. Revision 1.1.2.1 2000/07/15 21:30:06 pierre
  5445. * Do not consider ASM inside a string as a assembler statement start
  5446. * Add .pas extension to edWriteBlock if no extension is choosen
  5447. Revision 1.1 2000/07/13 09:48:37 michael
  5448. + Initial import
  5449. Revision 1.95 2000/06/22 09:07:13 pierre
  5450. * Gabor changes: see fixes.txt
  5451. Revision 1.94 2000/06/16 21:17:39 pierre
  5452. + TCustoCodeEditorCore.GetChangedLine
  5453. Revision 1.93 2000/06/16 08:50:43 pierre
  5454. + new bunch of Gabor's changes
  5455. Revision 1.92 2000/06/15 20:29:45 pierre
  5456. * avoid RTE 211 on Ctrl K W
  5457. Revision 1.91 2000/05/29 10:44:58 pierre
  5458. + New bunch of Gabor's changes: see fixes.txt
  5459. Revision 1.90 2000/05/17 11:58:26 pierre
  5460. * remove openbrace because of multiple comment level problem
  5461. Revision 1.89 2000/05/17 09:44:46 pierre
  5462. * fix the $ifdef inside a comment problem
  5463. Revision 1.88 2000/04/25 08:42:34 pierre
  5464. * New Gabor changes : see fixes.txt
  5465. Revision 1.87 2000/04/18 11:42:38 pierre
  5466. lot of Gabor changes : see fixes.txt
  5467. Revision 1.86 2000/03/23 21:36:19 pierre
  5468. * get correct position in indicator again
  5469. Revision 1.85 2000/03/21 23:17:47 pierre
  5470. + Gabor patch to add support for multiple windows
  5471. of same file
  5472. weditor has been splitted into weditor and wcedit units
  5473. Revision 1.84 2000/03/20 19:19:44 pierre
  5474. * LFN support in streams
  5475. Revision 1.83 2000/03/14 13:38:03 pierre
  5476. * max number of line changed and warning added
  5477. Revision 1.82 2000/03/02 22:33:36 pierre
  5478. * Grep improoved
  5479. Revision 1.81 2000/02/09 12:56:54 pierre
  5480. * fix for DelChar past end of line
  5481. Revision 1.80 2000/02/07 12:11:15 pierre
  5482. Gabors changes
  5483. Revision 1.79 2000/02/05 14:50:59 florian
  5484. * applied fix from Gabor regarding the limited line length of the clipboard
  5485. Revision 1.78 2000/01/28 22:20:04 pierre
  5486. * Test_partial_syntax released
  5487. Revision 1.77 2000/01/27 22:30:38 florian
  5488. * start of FPU window
  5489. * current executed line color has a higher priority then a breakpoint now
  5490. Revision 1.76 2000/01/25 00:12:23 pierre
  5491. * fix for Backspace Undo
  5492. Revision 1.75 2000/01/14 15:36:42 pierre
  5493. + GetShortFileName used for tcodeeditor file opening
  5494. Revision 1.74 2000/01/10 23:20:04 pierre
  5495. * problem with Paste solved
  5496. Revision 1.73 2000/01/10 13:25:46 pierre
  5497. + first partial syntax test
  5498. Revision 1.72 2000/01/07 00:19:30 pierre
  5499. * forgot CommentLineType check to see if we need to update format
  5500. on next line
  5501. * some changes for TEST_PARTIAL_SYNTAX still does notwork :(
  5502. Revision 1.71 2000/01/06 17:47:26 pierre
  5503. * avoid to resyntax whole source in unnecessary cases
  5504. Revision 1.70 2000/01/05 17:35:50 pierre
  5505. + Warning box if a line is cut at reading of file
  5506. this is done to avoid loosing completely long lines
  5507. * several TAB related changes
  5508. in particular do not remove or recombine TABs in makefiles
  5509. * fixes for ^KR and ^KW (the was an extra LF at end of
  5510. written block of disk and an error for starting X position
  5511. in SaveAreaToStream)
  5512. Revision 1.69 2000/01/05 00:37:34 pierre
  5513. * ^KC fix
  5514. * better Tab handling
  5515. Revision 1.68 2000/01/04 12:33:08 pierre
  5516. * reinserted version 1.66 lost changes
  5517. + CtrlT Undo works now !
  5518. Revision 1.67 2000/01/03 11:38:35 michael
  5519. Changes from Gabor
  5520. Revision 1.65 1999/12/08 16:02:46 pierre
  5521. * fix for bugs 746,748 and 750
  5522. Revision 1.64 1999/12/01 17:25:00 pierre
  5523. + check if file on disk was changed since load before overwriting
  5524. Revision 1.63 1999/11/22 17:34:08 pierre
  5525. * fix for form bug 634
  5526. Revision 1.62 1999/11/18 13:42:06 pierre
  5527. * Some more Undo stuff
  5528. Revision 1.61 1999/11/10 00:45:30 pierre
  5529. + groupd action started, not yet working
  5530. Revision 1.60 1999/11/05 13:49:13 pierre
  5531. * WinPaste depends on avalaible Clipboard data
  5532. Revision 1.59 1999/11/03 09:39:23 peter
  5533. * fixed uppercase filenames
  5534. * savetostream did twice a -1 on the linecount, so the lastline of a
  5535. file wasn't saved correctly
  5536. Revision 1.58 1999/10/28 15:14:22 pierre
  5537. * get it to compile with debug conditional
  5538. Revision 1.56 1999/10/27 13:32:58 pierre
  5539. * some more Undo Fixes
  5540. Revision 1.55 1999/10/27 10:46:19 pierre
  5541. * More Undo/Redo stuff
  5542. Revision 1.54 1999/10/25 16:49:05 pierre
  5543. + Undo/Redo by Visa Harvey (great thanks) inserted
  5544. (with some modifications)
  5545. Moves work correctly
  5546. Text insertion/deletion are still buggy !
  5547. * LinePosToCharIndex and reverse function changed to get more
  5548. sensible results, dependant code adapted
  5549. * several bug fixes
  5550. Revision 1.53 1999/10/14 10:21:48 pierre
  5551. * more tabs related problems fiwes
  5552. Revision 1.52 1999/10/12 23:35:18 pierre
  5553. + DelStart and SelectWord implemented
  5554. * AddChar(tab) now reacts correctly if efAutoIndent is set
  5555. Revision 1.51 1999/10/08 15:24:50 pierre
  5556. * InsertFrom bug (end of line wasdiscarded)
  5557. Revision 1.50 1999/09/28 23:44:13 pierre
  5558. * text insertion in middle of line was buggy
  5559. Revision 1.49 1999/09/23 16:33:30 pierre
  5560. * ^B^A now prints out the ascii 1 char
  5561. * In SearchReplace Several occurence of a pattern in the same line
  5562. should now be found correctly
  5563. Revision 1.48 1999/09/22 16:16:26 pierre
  5564. + added HistLists for several dialogs
  5565. Revision 1.47 1999/09/21 17:08:59 pierre
  5566. + Windows clipboard for win32
  5567. Revision 1.46 1999/09/13 16:24:44 peter
  5568. + clock
  5569. * backspace unident like tp7
  5570. Revision 1.45 1999/09/09 12:05:33 pierre
  5571. + Copy/Paste to Windows Clipboard
  5572. + efLeaveTrailingSpaces added to editor flags
  5573. (if not set then spaces at the end of a line are
  5574. removed on writing the file)
  5575. Revision 1.44 1999/08/27 15:07:44 pierre
  5576. + cmResetDebuggerRow
  5577. Revision 1.43 1999/08/24 22:04:35 pierre
  5578. + TCodeEditor.SetDebuggerRow
  5579. works like SetHighlightRow but is only disposed by a SetDebuggerRow(-1)
  5580. so the current stop point in debugging is not lost if
  5581. we move the cursor
  5582. Revision 1.42 1999/08/22 22:20:30 pierre
  5583. * selection extension bug removed, via oldEvent pointer in TCodeEditor.HandleEvent
  5584. Revision 1.41 1999/08/16 18:25:28 peter
  5585. * Adjusting the selection when the editor didn't contain any line.
  5586. * Reserved word recognition redesigned, but this didn't affect the overall
  5587. syntax highlight speed remarkably (at least not on my Amd-K6/350).
  5588. The syntax scanner loop is a bit slow but the main problem is the
  5589. recognition of special symbols. Switching off symbol processing boosts
  5590. the performance up to ca. 200%...
  5591. * The editor didn't allow copying (for ex to clipboard) of a single character
  5592. * 'File|Save as' caused permanently run-time error 3. Not any more now...
  5593. * Compiler Messages window (actually the whole desktop) did not act on any
  5594. keypress when compilation failed and thus the window remained visible
  5595. + Message windows are now closed upon pressing Esc
  5596. + At 'Run' the IDE checks whether any sources are modified, and recompiles
  5597. only when neccessary
  5598. + BlockRead and BlockWrite (Ctrl+K+R/W) implemented in TCodeEditor
  5599. + LineSelect (Ctrl+K+L) implemented
  5600. * The IDE had problems closing help windows before saving the desktop
  5601. Revision 1.40 1999/08/03 20:22:42 peter
  5602. + TTab acts now on Ctrl+Tab and Ctrl+Shift+Tab...
  5603. + Desktop saving should work now
  5604. - History saved
  5605. - Clipboard content saved
  5606. - Desktop saved
  5607. - Symbol info saved
  5608. * syntax-highlight bug fixed, which compared special keywords case sensitive
  5609. (for ex. 'asm' caused asm-highlighting, while 'ASM' didn't)
  5610. * with 'whole words only' set, the editor didn't found occourences of the
  5611. searched text, if the text appeared previously in the same line, but didn't
  5612. satisfied the 'whole-word' condition
  5613. * ^QB jumped to (SelStart.X,SelEnd.X) instead of (SelStart.X,SelStart.Y)
  5614. (ie. the beginning of the selection)
  5615. * when started typing in a new line, but not at the start (X=0) of it,
  5616. the editor inserted the text one character more to left as it should...
  5617. * TCodeEditor.HideSelection (Ctrl-K+H) didn't update the screen
  5618. * Shift shouldn't cause so much trouble in TCodeEditor now...
  5619. * Syntax highlight had problems recognizing a special symbol if it was
  5620. prefixed by another symbol character in the source text
  5621. * Auto-save also occours at Dos shell, Tool execution, etc. now...
  5622. Revision 1.39 1999/07/28 23:11:26 peter
  5623. * fixes from gabor
  5624. Revision 1.38 1999/07/12 13:14:24 pierre
  5625. * LineEnd bug corrected, now goes end of text even if selected
  5626. + Until Return for debugger
  5627. + Code for Quit inside GDB Window
  5628. Revision 1.37 1999/06/29 22:50:16 peter
  5629. * more fixes from gabor
  5630. Revision 1.36 1999/06/29 08:51:34 pierre
  5631. * lockflag problems fixed
  5632. Revision 1.35 1999/06/28 19:32:32 peter
  5633. * fixes from gabor
  5634. Revision 1.34 1999/06/28 15:58:07 pierre
  5635. * ShiftDel problem solved
  5636. Revision 1.33 1999/06/25 00:31:51 pierre
  5637. + FileDir remembers the last directory for Open and Save
  5638. Revision 1.32 1999/06/21 23:36:12 pierre
  5639. * Size for Cluster is word (TP compatibility)
  5640. Revision 1.31 1999/05/22 13:44:35 peter
  5641. * fixed couple of bugs
  5642. Revision 1.30 1999/04/15 08:58:10 peter
  5643. * syntax highlight fixes
  5644. * browser updates
  5645. Revision 1.29 1999/04/07 21:55:59 peter
  5646. + object support for browser
  5647. * html help fixes
  5648. * more desktop saving things
  5649. * NODEBUG directive to exclude debugger
  5650. Revision 1.28 1999/03/23 15:11:39 peter
  5651. * desktop saving things
  5652. * vesa mode
  5653. * preferences dialog
  5654. Revision 1.27 1999/03/08 14:58:17 peter
  5655. + prompt with dialogs for tools
  5656. Revision 1.26 1999/03/07 22:58:57 pierre
  5657. * FindRec needs longint for CheckBoxes
  5658. Revision 1.25 1999/03/05 17:39:39 pierre
  5659. * Actions item freeing
  5660. Revision 1.24 1999/03/03 16:45:07 pierre
  5661. * Actions were not dispose in TCodeEditor.Done
  5662. Revision 1.23 1999/03/01 15:42:10 peter
  5663. + Added dummy entries for functions not yet implemented
  5664. * MenuBar didn't update itself automatically on command-set changes
  5665. * Fixed Debugging/Profiling options dialog
  5666. * TCodeEditor converts spaces to tabs at save only if efUseTabChars is set
  5667. * efBackSpaceUnindents works correctly
  5668. + 'Messages' window implemented
  5669. + Added '$CAP MSG()' and '$CAP EDIT' to available tool-macros
  5670. + Added TP message-filter support (for ex. you can call GREP thru
  5671. GREP2MSG and view the result in the messages window - just like in TP)
  5672. * A 'var' was missing from the param-list of THelpFacility.TopicSearch,
  5673. so topic search didn't work...
  5674. * In FPHELP.PAS there were still context-variables defined as word instead
  5675. of THelpCtx
  5676. * StdStatusKeys() was missing from the statusdef for help windows
  5677. + Topic-title for index-table can be specified when adding a HTML-files
  5678. Revision 1.22 1999/02/22 02:15:25 peter
  5679. + default extension for save in the editor
  5680. + Separate Text to Find for the grep dialog
  5681. * fixed redir crash with tp7
  5682. Revision 1.21 1999/02/20 15:18:33 peter
  5683. + ctrl-c capture with confirm dialog
  5684. + ascii table in the tools menu
  5685. + heapviewer
  5686. * empty file fixed
  5687. * fixed callback routines in fpdebug to have far for tp7
  5688. Revision 1.20 1999/02/18 17:27:57 pierre
  5689. * find/replace dialogs need packed records !!
  5690. Revision 1.19 1999/02/18 13:44:36 peter
  5691. * search fixed
  5692. + backward search
  5693. * help fixes
  5694. * browser updates
  5695. Revision 1.18 1999/02/15 15:12:25 pierre
  5696. + TLine remembers Comment type
  5697. Revision 1.17 1999/02/15 09:32:58 pierre
  5698. * single line comment // fix : comments intermix still wrong !!
  5699. Revision 1.16 1999/02/11 19:07:26 pierre
  5700. * GDBWindow redesigned :
  5701. normal editor apart from
  5702. that any kbEnter will send the line (for begin to cursor)
  5703. to GDB command !
  5704. GDBWindow opened in Debugger Menu
  5705. still buggy :
  5706. -echo should not be present if at end of text
  5707. -GDBWindow becomes First after each step (I don't know why !)
  5708. Revision 1.15 1999/02/09 09:29:59 pierre
  5709. * avoid invisible characters in CombineColors
  5710. Revision 1.14 1999/02/05 13:51:45 peter
  5711. * unit name of FPSwitches -> FPSwitch which is easier to use
  5712. * some fixes for tp7 compiling
  5713. Revision 1.13 1999/02/05 13:22:43 pierre
  5714. * bug that caused crash for empty files
  5715. Revision 1.12 1999/02/05 12:04:56 pierre
  5716. + 'loose' centering for debugger
  5717. Revision 1.11 1999/02/04 17:19:26 peter
  5718. * linux fixes
  5719. Revision 1.10 1999/02/04 10:13:00 pierre
  5720. + GetCurrentWord (used in Find/Replace)
  5721. + DefUseTabsPattern (pattern forcing tabs to be kept)
  5722. used for all makefiles !!
  5723. Revision 1.9 1999/01/29 10:34:33 peter
  5724. + needobjdir,needlibdir
  5725. Revision 1.8 1999/01/21 11:54:31 peter
  5726. + tools menu
  5727. + speedsearch in symbolbrowser
  5728. * working run command
  5729. Revision 1.7 1999/01/14 21:41:17 peter
  5730. * use * as modified indicator
  5731. * fixed syntax highlighting
  5732. Revision 1.6 1999/01/12 14:29:44 peter
  5733. + Implemented still missing 'switch' entries in Options menu
  5734. + Pressing Ctrl-B sets ASCII mode in editor, after which keypresses (even
  5735. ones with ASCII < 32 ; entered with Alt+<###>) are interpreted always as
  5736. ASCII chars and inserted directly in the text.
  5737. + Added symbol browser
  5738. * splitted fp.pas to fpide.pas
  5739. Revision 1.5 1999/01/07 15:02:40 peter
  5740. * better tab support
  5741. Revision 1.4 1999/01/04 11:49:55 peter
  5742. * 'Use tab characters' now works correctly
  5743. + Syntax highlight now acts on File|Save As...
  5744. + Added a new class to syntax highlight: 'hex numbers'.
  5745. * There was something very wrong with the palette managment. Now fixed.
  5746. + Added output directory (-FE<xxx>) support to 'Directories' dialog...
  5747. * Fixed some possible bugs in Running/Compiling, and the compilation/run
  5748. process revised
  5749. Revision 1.2 1998/12/28 15:47:55 peter
  5750. + Added user screen support, display & window
  5751. + Implemented Editor,Mouse Options dialog
  5752. + Added location of .INI and .CFG file
  5753. + Option (INI) file managment implemented (see bottom of Options Menu)
  5754. + Switches updated
  5755. + Run program
  5756. Revision 1.4 1998/12/27 12:01:23 gabor
  5757. * efXXXX constants revised for BP compatibility
  5758. * fixed column and row highlighting (needs to rewrite default palette in the INI)
  5759. Revision 1.3 1998/12/22 10:39:54 peter
  5760. + options are now written/read
  5761. + find and replace routines
  5762. }