weditor.pas 199 KB

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