weditor.pas 198 KB

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