weditor.pas 195 KB

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