2
0

weditor.pas 197 KB

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