weditor.pas 199 KB

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