weditor.pas 161 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969
  1. {
  2. $Id$
  3. This file is part of the Free Pascal Integrated Development Environment
  4. Copyright (c) 1998 by Berczi Gabor
  5. Code editor template objects
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. {$I globdir.inc}
  13. unit WEditor;
  14. interface
  15. {tes}
  16. uses
  17. Dos,Objects,Drivers,Views,Menus,Commands,
  18. WUtils;
  19. const
  20. cmFileNameChanged = 51234;
  21. cmASCIIChar = 51235;
  22. cmClearLineHighlights = 51236;
  23. cmSaveCancelled = 51237;
  24. cmBreakLine = 51238;
  25. cmSelStart = 51239;
  26. cmSelEnd = 51240;
  27. cmLastCursorPos = 51241;
  28. cmIndentBlock = 51242;
  29. cmUnIndentBlock = 51243;
  30. cmSelectLine = 51244;
  31. cmWriteBlock = 51245;
  32. cmReadBlock = 51246;
  33. cmPrintBlock = 51247;
  34. cmResetDebuggerRow = 51248;
  35. cmAddChar = 51249;
  36. cmExpandCodeTemplate = 51250;
  37. EditorTextBufSize = {$ifdef FPC}32768{$else} 4096{$endif};
  38. MaxLineLength = {$ifdef FPC} 255{$else} 255{$endif};
  39. MaxLineCount = {$ifdef FPC}2000000{$else}16380{$endif};
  40. CodeCompleteMinLen = 4; { minimum length of text to try to complete }
  41. efBackupFiles = $00000001;
  42. efInsertMode = $00000002;
  43. efAutoIndent = $00000004;
  44. efUseTabCharacters = $00000008;
  45. efBackSpaceUnindents = $00000010;
  46. efPersistentBlocks = $00000020;
  47. efSyntaxHighlight = $00000040;
  48. efBlockInsCursor = $00000080;
  49. efVerticalBlocks = $00000100;
  50. efHighlightColumn = $00000200;
  51. efHighlightRow = $00000400;
  52. efAutoBrackets = $00000800;
  53. efExpandAllTabs = $00001000;
  54. efKeepTrailingSpaces = $00002000;
  55. efCodeComplete = $00004000;
  56. efStoreContent = $80000000;
  57. attrAsm = 1;
  58. attrComment = 2;
  59. attrForceFull = 128;
  60. attrAll = attrAsm+attrComment;
  61. edOutOfMemory = 0;
  62. edReadError = 1;
  63. edWriteError = 2;
  64. edCreateError = 3;
  65. edSaveModify = 4;
  66. edSaveUntitled = 5;
  67. edSaveAs = 6;
  68. edFind = 7;
  69. edSearchFailed = 8;
  70. edReplace = 9;
  71. edReplacePrompt = 10;
  72. edTooManyLines = 11;
  73. edGotoLine = 12;
  74. edReplaceFile = 13;
  75. edWriteBlock = 14;
  76. edReadBlock = 15;
  77. edFileOnDiskChanged = 16;
  78. edChangedOnloading = 17;
  79. edSaveError = 18;
  80. ffmOptions = $0007; ffsOptions = 0;
  81. ffmDirection = $0008; ffsDirection = 3;
  82. ffmScope = $0010; ffsScope = 4;
  83. ffmOrigin = $0020; ffsOrigin = 5;
  84. ffDoReplace = $0040;
  85. ffReplaceAll = $0080;
  86. ffCaseSensitive = $0001;
  87. ffWholeWordsOnly = $0002;
  88. ffPromptOnReplace = $0004;
  89. ffForward = $0000;
  90. ffBackward = $0008;
  91. ffGlobal = $0000;
  92. ffSelectedText = $0010;
  93. ffFromCursor = $0000;
  94. ffEntireScope = $0020;
  95. coTextColor = 0;
  96. coWhiteSpaceColor = 1;
  97. coCommentColor = 2;
  98. coReservedWordColor = 3;
  99. coIdentifierColor = 4;
  100. coStringColor = 5;
  101. coNumberColor = 6;
  102. coAssemblerColor = 7;
  103. coSymbolColor = 8;
  104. coDirectiveColor = 9;
  105. coHexNumberColor = 10;
  106. coTabColor = 11;
  107. coBreakColor = 12;
  108. coFirstColor = 0;
  109. coLastColor = coBreakColor;
  110. lfBreakpoint = $0001;
  111. lfHighlightRow = $0002;
  112. lfDebuggerRow = $0004;
  113. eaMoveCursor = 1;
  114. eaInsertLine = 2;
  115. eaInsertText = 3;
  116. eaDeleteLine = 4;
  117. eaDeleteText = 5;
  118. eaSelectionChanged = 6;
  119. eaCut = 7;
  120. eaPaste = 8;
  121. eaPasteWin = 9;
  122. eaClear = 10;
  123. LastAction = eaClear;
  124. ActionString : array [0..LastAction] of string[8] =
  125. ('','Move','InsLine','InsText','DelLine','DelText',
  126. 'SelCh','Cut','Paste','PasteWin','Clear');
  127. CIndicator = #2#3#1;
  128. CEditor = #33#34#35#36#37#38#39#40#41#42#43#44#45#46#47#48#49;
  129. TAB = #9;
  130. FindStrSize = 79;
  131. type
  132. PCustomCodeEditor = ^TCustomCodeEditor;
  133. PEditorLineInfo = ^TEditorLineInfo;
  134. TEditorLineInfo = object(TObject)
  135. Editor: PCustomCodeEditor;
  136. Format : PString;
  137. BeginsWithAsm,
  138. EndsWithAsm : boolean;
  139. BeginsWithComment,
  140. EndsInSingleLineComment,
  141. EndsWithComment : boolean;
  142. BeginsWithDirective,
  143. EndsWithDirective : boolean;
  144. BeginCommentType,EndCommentType : byte;
  145. constructor Init(AEditor: PCustomCodeEditor);
  146. destructor Done; virtual;
  147. function GetFormat: string;
  148. procedure SetFormat(const AFormat: string);
  149. { Syntax information is now generated separately for each editor instance.
  150. This is not neccessary for a one-language IDE, but this unit contains
  151. a _generic_ editor object, which should be (and is) as flexible as
  152. possible.
  153. The overhead caused by generating the same syntax info for ex.
  154. twice isn't so much... - Gabor }
  155. end;
  156. PEditorLineInfoCollection = ^TEditorLineInfoCollection;
  157. TEditorLineInfoCollection = object(TCollection)
  158. function At(Index: sw_Integer): PEditorLineInfo;
  159. end;
  160. PCustomLine = ^TCustomLine;
  161. TCustomLine = object(TObject)
  162. constructor Init(const AText: string; AFlags: longint);
  163. {a}function GetText: string; virtual;
  164. {a}procedure SetText(const AText: string); virtual;
  165. {a}function GetEditorInfo(Editor: PCustomCodeEditor): PEditorLineInfo; virtual;
  166. {a}function GetFlags: longint; virtual;
  167. {a}procedure SetFlags(AFlags: longint); virtual;
  168. function IsFlagSet(AFlag: longint): boolean;
  169. procedure SetFlagState(AFlag: longint; ASet: boolean);
  170. destructor Done; virtual;
  171. public { internal use only! }
  172. {a}procedure AddEditorInfo(Index: sw_integer; AEditor: PCustomCodeEditor); virtual;
  173. {a}procedure RemoveEditorInfo(AEditor: PCustomCodeEditor); virtual;
  174. end;
  175. PLineCollection = ^TLineCollection;
  176. TLineCollection = object(TCollection)
  177. function At(Index: sw_Integer): PCustomLine;
  178. end;
  179. {$ifdef Undo}
  180. PEditorAction = ^TEditorAction;
  181. TEditorAction = object(TObject)
  182. StartPos : TPoint;
  183. EndPos : TPoint;
  184. Text : PString;
  185. ActionCount : longint;
  186. Action : byte;
  187. TimeStamp : longint; { this is needed to keep track of line number &
  188. position changes (for ex. for symbol browser)
  189. the line&pos references (eg. symbol info) should
  190. also contain such a timestamp. this will enable
  191. to determine which changes have been made since
  192. storage of the information and thus calculate
  193. the (probably) changed line & position information,
  194. so, we can still jump to the right position in the
  195. editor even when it is heavily modified - Gabor }
  196. constructor init(act:byte; StartP,EndP:TPoint;Txt:String);
  197. constructor init_group(act:byte);
  198. function is_grouped_action : boolean;
  199. destructor done; virtual;
  200. end;
  201. PEditorActionCollection = ^TEditorActionCollection;
  202. TEditorActionCollection = object(TCollection)
  203. CurrentGroupedAction : PEditorAction;
  204. function At(Idx : sw_integer) : PEditorAction;
  205. end;
  206. {$else}
  207. PEditorAction = ^TEditorAction;
  208. TEditorAction = packed record
  209. StartPos : TPoint;
  210. EndPos : TPoint;
  211. Text : PString;
  212. ActionCount : longint;
  213. Action : byte;
  214. TimeStamp : longint; { see above! }
  215. end;
  216. PEditorActionCollection = ^TEditorActionCollection;
  217. TEditorActionCollection = object(TCollection)
  218. function At(Idx : sw_integer) : PEditorAction;
  219. procedure FreeItem(Item: Pointer); virtual;
  220. end;
  221. {$endif Undo}
  222. TSpecSymbolClass =
  223. (ssCommentPrefix,ssCommentSingleLinePrefix,ssCommentSuffix,ssStringPrefix,ssStringSuffix,
  224. ssDirectivePrefix,ssDirectiveSuffix,ssAsmPrefix,ssAsmSuffix);
  225. TEditorBookMark = record
  226. Valid : boolean;
  227. Pos : TPoint;
  228. end;
  229. TCompleteState = (csInactive,csOffering,csDenied);
  230. PEditorBinding = ^TEditorBinding;
  231. PEditorBindingCollection = ^TEditorBindingCollection;
  232. TEditorBindingCollection = object(TCollection)
  233. function At(Index: sw_Integer): PEditorBinding;
  234. end;
  235. TEditorBinding = object(TObject)
  236. Editor : PCustomCodeEditor;
  237. constructor Init(AEditor: PCustomCodeEditor);
  238. destructor Done; virtual;
  239. end;
  240. PCustomCodeEditorCore = ^TCustomCodeEditorCore;
  241. TCustomCodeEditorCore = object(TObject)
  242. {$ifdef TP}public{$else}protected{$endif}
  243. Bindings : PEditorBindingCollection;
  244. LockFlag : sw_integer;
  245. ChangedLine : sw_integer;
  246. ContentsChangedCalled : boolean;
  247. LimitsChangedCalled : boolean;
  248. ModifiedChangedCalled : boolean;
  249. TabSizeChangedCalled : boolean;
  250. StoreUndoChangedCalled : boolean;
  251. {$ifdef TEST_PARTIAL_SYNTAX}
  252. LastSyntaxedLine : sw_integer;
  253. SyntaxComplete : boolean;
  254. {$endif TEST_PARTIAL_SYNTAX}
  255. public
  256. constructor Init;
  257. procedure BindEditor(AEditor: PCustomCodeEditor);
  258. procedure UnBindEditor(AEditor: PCustomCodeEditor);
  259. function IsEditorBound(AEditor: PCustomCodeEditor): boolean;
  260. function GetBindingCount: sw_integer;
  261. function GetBindingIndex(AEditor: PCustomCodeEditor): sw_integer;
  262. function SearchBinding(AEditor: PCustomCodeEditor): PEditorBinding;
  263. function CanDispose: boolean;
  264. destructor Done; virtual;
  265. public
  266. {a}function GetModified: boolean; virtual;
  267. {a}procedure SetModified(AModified: boolean); virtual;
  268. {a}function GetStoreUndo: boolean; virtual;
  269. {a}procedure SetStoreUndo(AStore: boolean); virtual;
  270. {a}function GetSyntaxCompleted: boolean; virtual;
  271. {a}procedure SetSyntaxCompleted(SC: boolean); virtual;
  272. {a}function GetTabSize: integer; virtual;
  273. {a}procedure SetTabSize(ATabSize: integer); virtual;
  274. function IsClipboard: Boolean;
  275. public
  276. { Notifications }
  277. procedure BindingsChanged;
  278. procedure ContentsChanged;
  279. procedure LimitsChanged;
  280. procedure ModifiedChanged;
  281. procedure TabSizeChanged;
  282. procedure StoreUndoChanged;
  283. {a}procedure DoContentsChanged; virtual;
  284. {a}procedure DoLimitsChanged; virtual;
  285. {a}procedure DoModifiedChanged; virtual;
  286. {a}procedure DoTabSizeChanged; virtual;
  287. {a}procedure DoStoreUndoChanged; virtual;
  288. {a}procedure DoSyntaxStateChanged; virtual;
  289. function GetLastVisibleLine : sw_integer;
  290. public
  291. { Storage }
  292. function LoadFromStream(Editor: PCustomCodeEditor; Stream: PStream): boolean; virtual;
  293. function SaveToStream(Editor: PCustomCodeEditor; Stream: PStream): boolean; virtual;
  294. function SaveAreaToStream(Editor: PCustomCodeEditor; Stream: PStream; StartP,EndP: TPoint): boolean; virtual;
  295. {$ifdef TP}public{$else}protected{$endif}
  296. { Text & info storage abstraction }
  297. {a}procedure ISetLineFlagState(Binding: PEditorBinding; LineNo: sw_integer; Flag: longint; ASet: boolean); virtual;
  298. {a}procedure IGetDisplayTextFormat(Binding: PEditorBinding; LineNo: sw_integer;var DT,DF:string); virtual;
  299. {a}function IGetLineFormat(Binding: PEditorBinding; LineNo: sw_integer): string; virtual;
  300. {a}procedure ISetLineFormat(Binding: PEditorBinding; LineNo: sw_integer;const S: string); virtual;
  301. public
  302. { Text & info storage abstraction }
  303. function CharIdxToLinePos(Line,CharIdx: sw_integer): sw_integer;
  304. function LinePosToCharIdx(Line,X: sw_integer): sw_integer;
  305. {a}function GetLineCount: sw_integer; virtual;
  306. {a}function GetLine(LineNo: sw_integer): PCustomLine; virtual;
  307. {a}function GetLineText(LineNo: sw_integer): string; virtual;
  308. {a}procedure SetDisplayText(I: sw_integer;const S: string); virtual;
  309. {a}function GetDisplayText(I: sw_integer): string; virtual;
  310. {a}procedure SetLineText(I: sw_integer;const S: string); virtual;
  311. procedure GetDisplayTextFormat(Editor: PCustomCodeEditor; I: sw_integer;var DT,DF:string); virtual;
  312. function GetLineFormat(Editor: PCustomCodeEditor; I: sw_integer): string; virtual;
  313. procedure SetLineFormat(Editor: PCustomCodeEditor; I: sw_integer;const S: string); virtual;
  314. {a}procedure DeleteAllLines; virtual;
  315. {a}procedure DeleteLine(I: sw_integer); virtual;
  316. {a}procedure InsertLine(LineNo: sw_integer; const S: string); virtual;
  317. {a}procedure AddLine(const S: string); virtual;
  318. {a}procedure GetContent(ALines: PUnsortedStringCollection); virtual;
  319. {a}procedure SetContent(ALines: PUnsortedStringCollection); virtual;
  320. public
  321. procedure Lock(AEditor: PCustomCodeEditor);
  322. procedure UnLock(AEditor: PCustomCodeEditor);
  323. function Locked: boolean;
  324. public
  325. { Syntax highlight }
  326. function UpdateAttrs(FromLine: sw_integer; Attrs: byte): sw_integer; virtual;
  327. function UpdateAttrsRange(FromLine, ToLine: sw_integer; Attrs: byte): sw_integer; virtual;
  328. function DoUpdateAttrs(Editor: PCustomCodeEditor; FromLine: sw_integer; Attrs: byte): sw_integer; virtual;
  329. function DoUpdateAttrsRange(Editor: PCustomCodeEditor; FromLine, ToLine: sw_integer;
  330. Attrs: byte): sw_integer; virtual;
  331. public
  332. { Undo info storage }
  333. {a}procedure AddAction(AAction: byte; AStartPos, AEndPos: TPoint; AText: string); virtual;
  334. {a}procedure AddGroupedAction(AAction : byte); virtual;
  335. {a}procedure CloseGroupedAction(AAction : byte); virtual;
  336. {a}function GetUndoActionCount: sw_integer; virtual;
  337. {a}function GetRedoActionCount: sw_integer; virtual;
  338. procedure UpdateUndoRedo(cm : word; action : byte);virtual;
  339. end;
  340. TCustomCodeEditor = object(TScroller)
  341. SelStart : TPoint;
  342. SelEnd : TPoint;
  343. Highlight : TRect;
  344. CurPos : TPoint;
  345. LockFlag : integer;
  346. NoSelect : Boolean;
  347. AlwaysShowScrollBars: boolean;
  348. public
  349. { constructor Load(var S: TStream);
  350. procedure Store(var S: TStream);}
  351. procedure ConvertEvent(var Event: TEvent); virtual;
  352. procedure HandleEvent(var Event: TEvent); virtual;
  353. procedure SetState(AState: Word; Enable: Boolean); virtual;
  354. procedure LocalMenu(P: TPoint); virtual;
  355. function GetLocalMenu: PMenu; virtual;
  356. function GetCommandTarget: PView; virtual;
  357. function CreateLocalMenuView(var Bounds: TRect; M: PMenu): PMenuPopup; virtual;
  358. function GetPalette: PPalette; virtual;
  359. public
  360. procedure Draw; virtual;
  361. procedure DrawCursor; virtual;
  362. procedure DrawIndicator; virtual;
  363. public
  364. {a}function GetFlags: longint; virtual;
  365. {a}procedure SetFlags(AFlags: longint); virtual;
  366. {a}function GetModified: boolean; virtual;
  367. {a}procedure SetModified(AModified: boolean); virtual;
  368. {a}function GetStoreUndo: boolean; virtual;
  369. {a}procedure SetStoreUndo(AStore: boolean); virtual;
  370. {a}function GetSyntaxCompleted: boolean; virtual;
  371. {a}procedure SetSyntaxCompleted(SC: boolean); virtual;
  372. {a}function GetLastSyntaxedLine: sw_integer; virtual;
  373. {a}procedure SetLastSyntaxedLine(ALine: sw_integer); virtual;
  374. function IsFlagSet(AFlag: longint): boolean;
  375. {a}function GetTabSize: integer; virtual;
  376. {a}procedure SetTabSize(ATabSize: integer); virtual;
  377. {a}function IsReadOnly: boolean; virtual;
  378. {a}function IsClipboard: Boolean; virtual;
  379. {a}function GetInsertMode: boolean; virtual;
  380. {a}procedure SetInsertMode(InsertMode: boolean); virtual;
  381. procedure SetCurPtr(X,Y: sw_integer); virtual;
  382. procedure SetSelection(A, B: TPoint); virtual;
  383. procedure SetHighlight(A, B: TPoint); virtual;
  384. procedure SetLineFlagState(LineNo: sw_integer; Flags: longint; ASet: boolean);
  385. procedure SetLineFlagExclusive(Flags: longint; LineNo: sw_integer);
  386. procedure Update; virtual;
  387. procedure ScrollTo(X, Y: sw_Integer);
  388. procedure TrackCursor(Center: boolean); virtual;
  389. procedure Lock; virtual;
  390. procedure UnLock; virtual;
  391. public
  392. { Text & info storage abstraction }
  393. {a}function GetLineCount: sw_integer; virtual;
  394. {a}function GetLine(LineNo: sw_integer): PCustomLine; virtual;
  395. {a}function CharIdxToLinePos(Line,CharIdx: sw_integer): sw_integer; virtual;
  396. {a}function LinePosToCharIdx(Line,X: sw_integer): sw_integer; virtual;
  397. {a}function GetLineText(I: sw_integer): string; virtual;
  398. {a}procedure SetDisplayText(I: sw_integer;const S: string); virtual;
  399. {a}function GetDisplayText(I: sw_integer): string; virtual;
  400. {a}procedure SetLineText(I: sw_integer;const S: string); virtual;
  401. {a}procedure GetDisplayTextFormat(I: sw_integer;var DT,DF:string); virtual;
  402. {a}function GetLineFormat(I: sw_integer): string; virtual;
  403. {a}procedure SetLineFormat(I: sw_integer;const S: string); virtual;
  404. {a}procedure DeleteAllLines; virtual;
  405. {a}procedure DeleteLine(I: sw_integer); virtual;
  406. {a}procedure InsertLine(LineNo: sw_integer; const S: string); virtual;
  407. {a}procedure AddLine(const S: string); virtual;
  408. {a}function GetErrorMessage: string; virtual;
  409. {a}procedure SetErrorMessage(const S: string); virtual;
  410. {a}procedure AdjustSelection(DeltaX, DeltaY: sw_integer);
  411. {a}procedure AdjustSelectionPos(CurPosX, CurPosY: sw_integer; DeltaX, DeltaY: sw_integer);
  412. {a}procedure GetContent(ALines: PUnsortedStringCollection); virtual;
  413. {a}procedure SetContent(ALines: PUnsortedStringCollection); virtual;
  414. {a}function LoadFromStream(Stream: PStream): boolean; virtual;
  415. {a}function SaveToStream(Stream: PStream): boolean; virtual;
  416. {a}function SaveAreaToStream(Stream: PStream; StartP,EndP: TPoint): boolean;
  417. public
  418. {a}function InsertFrom(Editor: PCustomCodeEditor): Boolean; virtual;
  419. {a}function InsertText(const S: string): Boolean; virtual;
  420. public
  421. procedure FlagsChanged(OldFlags: longint); virtual;
  422. {a}procedure BindingsChanged; virtual;
  423. procedure ContentsChanged; virtual;
  424. procedure LimitsChanged; virtual;
  425. procedure ModifiedChanged; virtual;
  426. procedure PositionChanged; virtual;
  427. procedure TabSizeChanged; virtual;
  428. procedure SyntaxStateChanged; virtual;
  429. procedure StoreUndoChanged; virtual;
  430. procedure SelectionChanged; virtual;
  431. procedure HighlightChanged; virtual;
  432. {a}procedure DoLimitsChanged; virtual;
  433. public
  434. { Syntax highlight support }
  435. {a}function GetSpecSymbolCount(SpecClass: TSpecSymbolClass): integer; virtual;
  436. {a}function GetSpecSymbol(SpecClass: TSpecSymbolClass; Index: integer): string; virtual;
  437. {a}function IsReservedWord(const S: string): boolean; virtual;
  438. public
  439. { CodeTemplate support }
  440. {a}function TranslateCodeTemplate(const Shortcut: string; ALines: PUnsortedStringCollection): boolean; virtual;
  441. { CodeComplete support }
  442. {a}function CompleteCodeWord(const WordS: string; var Text: string): boolean; virtual;
  443. {a}function GetCodeCompleteWord: string; virtual;
  444. {a}procedure SetCodeCompleteWord(const S: string); virtual;
  445. {a}function GetCodeCompleteFrag: string; virtual;
  446. {a}procedure SetCodeCompleteFrag(const S: string); virtual;
  447. function GetCompleteState: TCompleteState; virtual;
  448. procedure SetCompleteState(AState: TCompleteState); virtual;
  449. procedure ClearCodeCompleteWord; virtual;
  450. public
  451. { Syntax highlight }
  452. {a}function UpdateAttrs(FromLine: sw_integer; Attrs: byte): sw_integer; virtual;
  453. {a}function UpdateAttrsRange(FromLine, ToLine: sw_integer; Attrs: byte): sw_integer; virtual;
  454. public
  455. { Undo info storage }
  456. {a}procedure AddAction(AAction: byte; AStartPos, AEndPos: TPoint; AText: string); virtual;
  457. {a}procedure AddGroupedAction(AAction : byte); virtual;
  458. {a}procedure CloseGroupedAction(AAction : byte); virtual;
  459. {a}function GetUndoActionCount: sw_integer; virtual;
  460. {a}function GetRedoActionCount: sw_integer; virtual;
  461. {$ifdef TP}public{$else}protected{$endif}
  462. LastLocalCmd: word;
  463. KeyState : Integer;
  464. Bookmarks : array[0..9] of TEditorBookmark;
  465. DrawCalled,
  466. DrawCursorCalled: boolean;
  467. CurEvent : PEvent;
  468. procedure DrawLines(FirstLine: sw_integer);
  469. function Overwrite: boolean;
  470. function IsModal: boolean;
  471. procedure CheckSels;
  472. procedure CodeCompleteCheck;
  473. procedure CodeCompleteApply;
  474. procedure CodeCompleteCancel;
  475. procedure UpdateUndoRedo(cm : word; action : byte);
  476. procedure HideHighlight;
  477. function ShouldExtend: boolean;
  478. function ValidBlock: boolean;
  479. public
  480. { Editor primitives }
  481. procedure SelectAll(Enable: boolean); virtual;
  482. public
  483. { Editor commands }
  484. SearchRunCount: integer;
  485. InASCIIMode: boolean;
  486. procedure Indent; virtual;
  487. procedure CharLeft; virtual;
  488. procedure CharRight; virtual;
  489. procedure WordLeft; virtual;
  490. procedure WordRight; virtual;
  491. procedure LineStart; virtual;
  492. procedure LineEnd; virtual;
  493. procedure LineUp; virtual;
  494. procedure LineDown; virtual;
  495. procedure PageUp; virtual;
  496. procedure PageDown; virtual;
  497. procedure TextStart; virtual;
  498. procedure TextEnd; virtual;
  499. procedure JumpSelStart; virtual;
  500. procedure JumpSelEnd; virtual;
  501. procedure JumpMark(MarkIdx: integer); virtual;
  502. procedure DefineMark(MarkIdx: integer); virtual;
  503. procedure JumpToLastCursorPos; virtual;
  504. function InsertNewLine: Sw_integer; virtual;
  505. procedure BreakLine; virtual;
  506. procedure BackSpace; virtual;
  507. procedure DelChar; virtual;
  508. procedure DelWord; virtual;
  509. procedure DelStart; virtual;
  510. procedure DelEnd; virtual;
  511. procedure DelLine; virtual;
  512. procedure InsMode; virtual;
  513. procedure StartSelect; virtual;
  514. procedure EndSelect; virtual;
  515. procedure DelSelect; virtual;
  516. procedure HideSelect; virtual;
  517. procedure CopyBlock; virtual;
  518. procedure MoveBlock; virtual;
  519. procedure IndentBlock; virtual;
  520. procedure UnindentBlock; virtual;
  521. procedure SelectWord; virtual;
  522. procedure SelectLine; virtual;
  523. procedure WriteBlock; virtual;
  524. procedure ReadBlock; virtual;
  525. procedure PrintBlock; virtual;
  526. procedure ExpandCodeTemplate; virtual;
  527. procedure AddChar(C: char); virtual;
  528. {$ifdef WinClipSupported}
  529. function ClipCopyWin: Boolean; virtual;
  530. function ClipPasteWin: Boolean; virtual;
  531. {$endif WinClipSupported}
  532. function ClipCopy: Boolean; virtual;
  533. procedure ClipCut; virtual;
  534. procedure ClipPaste; virtual;
  535. function GetCurrentWord : string;
  536. procedure Undo; virtual;
  537. procedure Redo; virtual;
  538. procedure Find; virtual;
  539. procedure Replace; virtual;
  540. procedure DoSearchReplace; virtual;
  541. procedure GotoLine; virtual;
  542. end;
  543. TCodeEditorDialog = function(Dialog: Integer; Info: Pointer): Word;
  544. const
  545. EOL : String[2] = {$ifdef Linux}#10;{$else}#13#10;{$endif}
  546. cmCopyWin = 240;
  547. cmPasteWin = 241;
  548. { History ID }
  549. FileId = 101;
  550. TextFindId = 105;
  551. TextReplaceID = 106;
  552. GotoID = 107;
  553. TextGrepId = 108;
  554. GrepArgsId = 109;
  555. { used for ShiftDel and ShiftIns to avoid
  556. GetShiftState to be considered for extending
  557. selection (PM) }
  558. DontConsiderShiftState: boolean = false;
  559. ToClipCmds : TCommandSet = ([cmCut,cmCopy,cmCopyWin]);
  560. FromClipCmds : TCommandSet = ([cmPaste]);
  561. FromWinClipCmds : TCommandSet = ([cmPasteWin]);
  562. NulClipCmds : TCommandSet = ([cmClear]);
  563. UndoCmd : TCommandSet = ([cmUndo]);
  564. RedoCmd : TCommandSet = ([cmRedo]);
  565. function ExtractTabs(S: string; TabSize: Sw_integer): string;
  566. function StdEditorDialog(Dialog: Integer; Info: Pointer): word;
  567. const
  568. DefaultSaveExt : string[12] = '.pas';
  569. FileDir : DirStr = '';
  570. EditorDialog : TCodeEditorDialog = StdEditorDialog;
  571. Clipboard : PCustomCodeEditor = nil;
  572. FindStr : String[FindStrSize] = '';
  573. ReplaceStr : String[FindStrSize] = '';
  574. FindFlags : word = ffPromptOnReplace;
  575. WhiteSpaceChars : set of char = [#0,#32,#255];
  576. TabChars : set of char = [#9];
  577. HashChars : set of char = ['#'];
  578. AlphaChars : set of char = ['A'..'Z','a'..'z','_'];
  579. NumberChars : set of char = ['0'..'9'];
  580. RealNumberChars : set of char = ['E','e','.'{,'+','-'}];
  581. procedure RegisterWEditor;
  582. implementation
  583. uses
  584. MsgBox,Dialogs,App,StdDlg,HistList,Validate,
  585. {$ifdef WinClipSupported}
  586. Strings,WinClip,
  587. {$endif WinClipSupported}
  588. WViews,WCEdit;
  589. type
  590. TFindDialogRec = packed record
  591. Find : String[FindStrSize];
  592. Options : Word{longint};
  593. { checkboxes need 32 bits PM }
  594. { reverted to word in dialogs.TCluster for TP compatibility (PM) }
  595. { anyhow its complete nonsense : you can only have 16 fields
  596. but use a longint to store it !! }
  597. Direction: word;{ and tcluster has word size }
  598. Scope : word;
  599. Origin : word;
  600. end;
  601. TReplaceDialogRec = packed record
  602. Find : String[FindStrSize];
  603. Replace : String[FindStrSize];
  604. Options : Word{longint};
  605. Direction: word;
  606. Scope : word;
  607. Origin : word;
  608. end;
  609. TGotoLineDialogRec = packed record
  610. LineNo : string[5];
  611. Lines : sw_integer;
  612. end;
  613. const
  614. kbShift = kbLeftShift+kbRightShift;
  615. const
  616. FirstKeyCount = 40;
  617. FirstKeys: array[0..FirstKeyCount * 2] of Word = (FirstKeyCount,
  618. Ord(^A), cmWordLeft, Ord(^B), cmJumpLine, Ord(^C), cmPageDown,
  619. Ord(^D), cmCharRight, Ord(^E), cmLineUp,
  620. Ord(^F), cmWordRight, Ord(^G), cmDelChar,
  621. Ord(^H), cmBackSpace, Ord(^J), cmExpandCodeTemplate,
  622. Ord(^K), $FF02, Ord(^L), cmSearchAgain,
  623. Ord(^M), cmNewLine, Ord(^N), cmBreakLine,
  624. Ord(^P), cmASCIIChar, Ord(^Q), $FF01,
  625. Ord(^R), cmPageUp, Ord(^S), cmCharLeft,
  626. Ord(^T), cmDelWord, Ord(^U), cmUndo,
  627. Ord(^V), cmInsMode, Ord(^X), cmLineDown,
  628. Ord(^Y), cmDelLine, kbLeft, cmCharLeft,
  629. kbRight, cmCharRight, kbCtrlLeft, cmWordLeft,
  630. kbCtrlRight, cmWordRight, kbHome, cmLineStart,
  631. kbEnd, cmLineEnd, kbUp, cmLineUp,
  632. kbDown, cmLineDown, kbPgUp, cmPageUp,
  633. kbPgDn, cmPageDown, kbCtrlPgUp, cmTextStart,
  634. kbCtrlPgDn, cmTextEnd, kbIns, cmInsMode,
  635. kbDel, cmDelChar, kbShiftIns, cmPaste,
  636. kbShiftDel, cmCut, kbCtrlIns, cmCopy,
  637. kbCtrlDel, cmClear);
  638. QuickKeyCount = 23;
  639. QuickKeys: array[0..QuickKeyCount * 2] of Word = (QuickKeyCount,
  640. Ord('A'), cmReplace, Ord('C'), cmTextEnd,
  641. Ord('D'), cmLineEnd, Ord('F'), cmFind,
  642. Ord('H'), cmDelStart, Ord('R'), cmTextStart,
  643. Ord('S'), cmLineStart, Ord('Y'), cmDelEnd,
  644. Ord('G'), cmJumpLine, Ord('A'), cmReplace,
  645. Ord('B'), cmSelStart, Ord('K'), cmSelEnd,
  646. Ord('P'), cmLastCursorPos,
  647. Ord('0'), cmJumpMark0, Ord('1'), cmJumpMark1, Ord('2'), cmJumpMark2,
  648. Ord('3'), cmJumpMark3, Ord('4'), cmJumpMark4, Ord('5'), cmJumpMark5,
  649. Ord('6'), cmJumpMark6, Ord('7'), cmJumpMark7, Ord('8'), cmJumpMark8,
  650. Ord('9'), cmJumpMark9);
  651. BlockKeyCount = 23;
  652. BlockKeys: array[0..BlockKeyCount * 2] of Word = (BlockKeyCount,
  653. Ord('B'), cmStartSelect, Ord('C'), cmCopyBlock,
  654. Ord('H'), cmHideSelect, Ord('K'), cmEndSelect,
  655. Ord('Y'), cmDelSelect, Ord('V'), cmMoveBlock,
  656. Ord('I'), cmIndentBlock, Ord('U'), cmUnindentBlock,
  657. Ord('T'), cmSelectWord, Ord('L'), cmSelectLine,
  658. Ord('W'), cmWriteBlock, Ord('R'), cmReadBlock,
  659. Ord('P'), cmPrintBlock,
  660. Ord('0'), cmSetMark0, Ord('1'), cmSetMark1, Ord('2'), cmSetMark2,
  661. Ord('3'), cmSetMark3, Ord('4'), cmSetMark4, Ord('5'), cmSetMark5,
  662. Ord('6'), cmSetMark6, Ord('7'), cmSetMark7, Ord('8'), cmSetMark8,
  663. Ord('9'), cmSetMark9);
  664. KeyMap: array[0..2] of Pointer = (@FirstKeys, @QuickKeys, @BlockKeys);
  665. function ScanKeyMap(KeyMap: Pointer; KeyCode: Word): Word;
  666. type
  667. pword = ^word;
  668. var
  669. p : pword;
  670. count : sw_word;
  671. begin
  672. p:=keymap;
  673. count:=p^;
  674. inc(p);
  675. while (count>0) do
  676. begin
  677. if (lo(p^)=lo(keycode)) and
  678. ((hi(p^)=0) or (hi(p^)=hi(keycode))) then
  679. begin
  680. inc(p);
  681. scankeymap:=p^;
  682. Exit;
  683. end;
  684. inc(p,2);
  685. dec(count);
  686. end;
  687. scankeymap:=0;
  688. end;
  689. function IsWordSeparator(C: char): boolean;
  690. begin
  691. IsWordSeparator:=C in[' ',#0,#255,':','=','''','"','.',',','/',';','$','#','(',')','<','>','^','*','+','-','?','&'];
  692. end;
  693. function IsSpace(C: char): boolean;
  694. begin
  695. IsSpace:=C in[' ',#0,#255];
  696. end;
  697. function LTrim(S: string): string;
  698. begin
  699. while (length(S)>0) and (S[1] in [#0,TAB,#32]) do
  700. Delete(S,1,1);
  701. LTrim:=S;
  702. end;
  703. { TAB are not same as spaces if UseTabs is set PM }
  704. function RTrim(S: string;cut_tabs : boolean): string;
  705. begin
  706. while (length(S)>0) and
  707. ((S[length(S)] in [#0,#32]) or
  708. ((S[Length(S)]=TAB) and cut_tabs)) do
  709. Delete(S,length(S),1);
  710. RTrim:=S;
  711. end;
  712. function Trim(S: string): string;
  713. begin
  714. Trim:=RTrim(LTrim(S),true);
  715. end;
  716. function EatIO: integer;
  717. begin
  718. EatIO:=IOResult;
  719. end;
  720. function ExistsFile(const FileName: string): boolean;
  721. var f: file;
  722. Exists: boolean;
  723. begin
  724. if FileName='' then Exists:=false else
  725. begin
  726. {$I-}
  727. Assign(f,FileName);
  728. Reset(f,1);
  729. Exists:=EatIO=0;
  730. Close(f);
  731. EatIO;
  732. {$I+}
  733. end;
  734. ExistsFile:=Exists;
  735. end;
  736. function Max(A,B: longint): longint;
  737. begin
  738. if A>B then Max:=A else Max:=B;
  739. end;
  740. function Min(A,B: longint): longint;
  741. begin
  742. if A<B then Min:=A else Min:=B;
  743. end;
  744. function StrToInt(const S: string): longint;
  745. var L: longint;
  746. C: integer;
  747. begin
  748. Val(S,L,C); if C<>0 then L:=-1;
  749. StrToInt:=L;
  750. end;
  751. function RExpand(const S: string; MinLen: byte): string;
  752. begin
  753. if length(S)<MinLen then
  754. RExpand:=S+CharStr(' ',MinLen-length(S))
  755. else
  756. RExpand:=S;
  757. end;
  758. function upper(const s : string) : string;
  759. var
  760. i : Sw_word;
  761. begin
  762. for i:=1 to length(s) do
  763. if s[i] in ['a'..'z'] then
  764. upper[i]:=char(byte(s[i])-32)
  765. else
  766. upper[i]:=s[i];
  767. upper[0]:=s[0];
  768. end;
  769. function DirAndNameOf(const Path: string): string;
  770. var D: DirStr; N: NameStr; E: ExtStr;
  771. begin
  772. FSplit(Path,D,N,E);
  773. DirAndNameOf:=D+N;
  774. end;
  775. type TPosOfs = {$ifdef TP}longint{$endif}{$ifdef FPC}comp{$endif};
  776. function PosToOfs(const X,Y: sw_integer): TPosOfs;
  777. type TPosRec = record LoI, HiI: sw_integer; end;
  778. var C: TPosRec;
  779. begin
  780. C.LoI:=X; C.HiI:=Y;
  781. PosToOfs:=TPosOfs(C);
  782. end;
  783. function PosToOfsP(const P: TPoint): TPosOfs;
  784. begin
  785. PosToOfsP:=PosToOfs(P.X,P.Y);
  786. end;
  787. function PointOfs(P: TPoint): TPosOfs;
  788. begin
  789. PointOfs:={longint(P.Y)*MaxLineLength+P.X}PosToOfsP(P);
  790. end;
  791. {$ifndef Undo}
  792. function NewEditorAction(AAction: byte; AStartPos, AEndPos: TPoint; AText: string): PEditorAction;
  793. var P: PEditorAction;
  794. begin
  795. New(P); FillChar(P^,SizeOf(P^),0);
  796. with P^ do
  797. begin
  798. Action:=AAction;
  799. StartPos:=AStartPos; EndPos:=AEndPos;
  800. Text:=NewStr(AText);
  801. end;
  802. NewEditorAction:=P;
  803. end;
  804. procedure DisposeEditorAction(P: PEditorAction);
  805. begin
  806. if P<>nil then
  807. begin
  808. if P^.Text<>nil then DisposeStr(P^.Text); P^.Text:=nil;
  809. Dispose(P);
  810. end;
  811. end;
  812. {$endif ndef Undo}
  813. function ExtractTabs(S: string; TabSize: Sw_integer): string;
  814. var
  815. P,PAdd: Sw_Word;
  816. begin
  817. p:=0;
  818. while p<length(s) do
  819. begin
  820. inc(p);
  821. if s[p]=TAB then
  822. begin
  823. PAdd:=TabSize-((p-1) mod TabSize);
  824. s:=copy(S,1,P-1)+CharStr(' ',PAdd)+copy(S,P+1,255);
  825. inc(P,PAdd-1);
  826. end;
  827. end;
  828. ExtractTabs:=S;
  829. end;
  830. function CompressUsingTabs(S: string; TabSize: byte): string;
  831. var TabS: string;
  832. P: byte;
  833. begin
  834. TabS:=CharStr(' ',TabSize);
  835. repeat
  836. P:=Pos(TabS,S);
  837. if P>0 then
  838. S:=copy(S,1,P-1)+TAB+copy(S,P+TabSize,255);
  839. until P=0;
  840. CompressUsingTabs:=S;
  841. end;
  842. {*****************************************************************************
  843. Forward/Backward Scanning
  844. *****************************************************************************}
  845. Const
  846. {$ifndef FPC}
  847. MaxBufLength = $7f00;
  848. NotFoundValue = -1;
  849. {$else}
  850. MaxBufLength = $7fffff00;
  851. NotFoundValue = -1;
  852. {$endif}
  853. Type
  854. Btable = Array[0..255] of Byte;
  855. Procedure BMFMakeTable(const s:string; Var t : Btable);
  856. Var
  857. x : sw_integer;
  858. begin
  859. FillChar(t,sizeof(t),length(s));
  860. For x := length(s) downto 1 do
  861. if (t[ord(s[x])] = length(s)) then
  862. t[ord(s[x])] := length(s) - x;
  863. end;
  864. function BMFScan(var Block; Size: Sw_Word;const Str: String;const bt:BTable): Sw_Integer;
  865. Var
  866. buffer : Array[0..MaxBufLength-1] of Byte Absolute block;
  867. s2 : String;
  868. len,
  869. numb : Sw_Word;
  870. found : Boolean;
  871. begin
  872. len:=length(str);
  873. if len>size then
  874. begin
  875. BMFScan := NotFoundValue;
  876. exit;
  877. end;
  878. s2[0]:=chr(len); { sets the length to that of the search String }
  879. found:=False;
  880. numb:=pred(len);
  881. While (not found) and (numb<size) do
  882. begin
  883. { partial match }
  884. if buffer[numb] = ord(str[len]) then
  885. begin
  886. { less partial! }
  887. if buffer[numb-pred(len)] = ord(str[1]) then
  888. begin
  889. move(buffer[numb-pred(len)],s2[1],len);
  890. if (str=s2) then
  891. begin
  892. found:=true;
  893. break;
  894. end;
  895. end;
  896. inc(numb);
  897. end
  898. else
  899. inc(numb,Bt[buffer[numb]]);
  900. end;
  901. if not found then
  902. BMFScan := NotFoundValue
  903. else
  904. BMFScan := numb - pred(len);
  905. end;
  906. function BMFIScan(var Block; Size: Sw_Word;const Str: String;const bt:BTable): Sw_Integer;
  907. Var
  908. buffer : Array[0..MaxBufLength-1] of Char Absolute block;
  909. len,
  910. numb,
  911. x : Sw_Word;
  912. found : Boolean;
  913. p : pchar;
  914. c : char;
  915. begin
  916. len:=length(str);
  917. if (len=0) or (len>size) then
  918. begin
  919. BMFIScan := NotFoundValue;
  920. exit;
  921. end;
  922. found:=False;
  923. numb:=pred(len);
  924. While (not found) and (numb<size) do
  925. begin
  926. { partial match }
  927. c:=buffer[numb];
  928. if c in ['a'..'z'] then
  929. c:=chr(ord(c)-32);
  930. if (c=str[len]) then
  931. begin
  932. { less partial! }
  933. p:=@buffer[numb-pred(len)];
  934. x:=1;
  935. while (x<=len) do
  936. begin
  937. if not(((p^ in ['a'..'z']) and (chr(ord(p^)-32)=str[x])) or
  938. (p^=str[x])) then
  939. break;
  940. inc(p);
  941. inc(x);
  942. end;
  943. if (x>len) then
  944. begin
  945. found:=true;
  946. break;
  947. end;
  948. inc(numb);
  949. end
  950. else
  951. inc(numb,Bt[ord(c)]);
  952. end;
  953. if not found then
  954. BMFIScan := NotFoundValue
  955. else
  956. BMFIScan := numb - pred(len);
  957. end;
  958. Procedure BMBMakeTable(const s:string; Var t : Btable);
  959. Var
  960. x : sw_integer;
  961. begin
  962. FillChar(t,sizeof(t),length(s));
  963. For x := 1 to length(s)do
  964. if (t[ord(s[x])] = length(s)) then
  965. t[ord(s[x])] := x-1;
  966. end;
  967. function BMBScan(var Block; Size: Sw_Word;const Str: String;const bt:BTable): Sw_Integer;
  968. Var
  969. buffer : Array[0..MaxBufLength-1] of Byte Absolute block;
  970. s2 : String;
  971. len,
  972. numb : Sw_integer;
  973. found : Boolean;
  974. begin
  975. len:=length(str);
  976. if len>size then
  977. begin
  978. BMBScan := NotFoundValue;
  979. exit;
  980. end;
  981. s2[0]:=chr(len); { sets the length to that of the search String }
  982. found:=False;
  983. numb:=size-pred(len);
  984. While (not found) and (numb>0) do
  985. begin
  986. { partial match }
  987. if buffer[numb] = ord(str[1]) then
  988. begin
  989. { less partial! }
  990. if buffer[numb+pred(len)] = ord(str[len]) then
  991. begin
  992. move(buffer[numb],s2[1],len);
  993. if (str=s2) then
  994. begin
  995. found:=true;
  996. break;
  997. end;
  998. end;
  999. dec(numb);
  1000. end
  1001. else
  1002. dec(numb,Bt[buffer[numb]]);
  1003. end;
  1004. if not found then
  1005. BMBScan := NotFoundValue
  1006. else
  1007. BMBScan := numb;
  1008. end;
  1009. function BMBIScan(var Block; Size: Sw_Word;const Str: String;const bt:BTable): Sw_Integer;
  1010. Var
  1011. buffer : Array[0..MaxBufLength-1] of Char Absolute block;
  1012. len,
  1013. numb,
  1014. x : Sw_integer;
  1015. found : Boolean;
  1016. p : pchar;
  1017. c : char;
  1018. begin
  1019. len:=length(str);
  1020. if (len=0) or (len>size) then
  1021. begin
  1022. BMBIScan := NotFoundValue;
  1023. exit;
  1024. end;
  1025. found:=False;
  1026. numb:=size-len;
  1027. While (not found) and (numb>0) do
  1028. begin
  1029. { partial match }
  1030. c:=buffer[numb];
  1031. if c in ['a'..'z'] then
  1032. c:=chr(ord(c)-32);
  1033. if (c=str[1]) then
  1034. begin
  1035. { less partial! }
  1036. p:=@buffer[numb];
  1037. x:=1;
  1038. while (x<=len) do
  1039. begin
  1040. if not(((p^ in ['a'..'z']) and (chr(ord(p^)-32)=str[x])) or
  1041. (p^=str[x])) then
  1042. break;
  1043. inc(p);
  1044. inc(x);
  1045. end;
  1046. if (x>len) then
  1047. begin
  1048. found:=true;
  1049. break;
  1050. end;
  1051. dec(numb);
  1052. end
  1053. else
  1054. dec(numb,Bt[ord(c)]);
  1055. end;
  1056. if not found then
  1057. BMBIScan := NotFoundValue
  1058. else
  1059. BMBIScan := numb;
  1060. end;
  1061. {*****************************************************************************
  1062. PLine,TLineCollection
  1063. *****************************************************************************}
  1064. constructor TCustomLine.Init(const AText: string; AFlags: longint);
  1065. begin
  1066. inherited Init;
  1067. SetText(AText);
  1068. end;
  1069. function TCustomLine.GetText: string;
  1070. begin
  1071. Abstract; GetText:='';
  1072. end;
  1073. procedure TCustomLine.SetText(const AText: string);
  1074. begin
  1075. Abstract;
  1076. end;
  1077. function TCustomLine.GetEditorInfo(Editor: PCustomCodeEditor): PEditorLineInfo;
  1078. begin
  1079. Abstract;
  1080. GetEditorInfo:=nil;
  1081. end;
  1082. function TCustomLine.GetFlags: longint;
  1083. begin
  1084. Abstract;
  1085. GetFlags:=0;
  1086. end;
  1087. procedure TCustomLine.SetFlags(AFlags: longint);
  1088. begin
  1089. Abstract;
  1090. end;
  1091. function TCustomLine.IsFlagSet(AFlag: longint): boolean;
  1092. begin
  1093. IsFlagSet:=(GetFlags and AFlag)=AFlag;
  1094. end;
  1095. procedure TCustomLine.SetFlagState(AFlag: longint; ASet: boolean);
  1096. var N,O: longint;
  1097. begin
  1098. O:=GetFlags; N:=O;
  1099. if ASet then
  1100. N:=N or AFlag
  1101. else
  1102. N:=N and (not AFlag);
  1103. if N<>O then
  1104. SetFlags(N);
  1105. end;
  1106. procedure TCustomLine.AddEditorInfo(Index: sw_integer; AEditor: PCustomCodeEditor);
  1107. begin
  1108. { Abstract }
  1109. end;
  1110. procedure TCustomLine.RemoveEditorInfo(AEditor: PCustomCodeEditor);
  1111. begin
  1112. { Abstract }
  1113. end;
  1114. destructor TCustomLine.Done;
  1115. begin
  1116. inherited Done;
  1117. end;
  1118. function TLineCollection.At(Index: sw_Integer): PCustomLine;
  1119. begin
  1120. At:=inherited At(Index);
  1121. end;
  1122. constructor TEditorLineInfo.Init(AEditor: PCustomCodeEditor);
  1123. begin
  1124. inherited Init;
  1125. Editor:=AEditor;
  1126. end;
  1127. function TEditorLineInfo.GetFormat: string;
  1128. begin
  1129. GetFormat:=GetStr(Format);
  1130. end;
  1131. procedure TEditorLineInfo.SetFormat(const AFormat: string);
  1132. begin
  1133. SetStr(Format,AFormat);
  1134. end;
  1135. destructor TEditorLineInfo.Done;
  1136. begin
  1137. if Format<>nil then DisposeStr(Format); Format:=nil;
  1138. inherited Done;
  1139. end;
  1140. function TEditorLineInfoCollection.At(Index: sw_Integer): PEditorLineInfo;
  1141. begin
  1142. At:=inherited At(Index);
  1143. end;
  1144. function TEditorBindingCollection.At(Index: sw_Integer): PEditorBinding;
  1145. begin
  1146. At:=inherited At(Index);
  1147. end;
  1148. constructor TEditorBinding.Init(AEditor: PCustomCodeEditor);
  1149. begin
  1150. inherited Init;
  1151. Editor:=AEditor;
  1152. end;
  1153. destructor TEditorBinding.Done;
  1154. begin
  1155. inherited Done;
  1156. end;
  1157. constructor TCustomCodeEditorCore.Init;
  1158. begin
  1159. inherited Init;
  1160. New(Bindings, Init(10,10));
  1161. end;
  1162. procedure TCustomCodeEditorCore.BindEditor(AEditor: PCustomCodeEditor);
  1163. var B: PEditorBinding;
  1164. Count,I,Idx: sw_integer;
  1165. L: PCustomLine;
  1166. begin
  1167. if Assigned(AEditor)=false then Exit;
  1168. New(B, Init(AEditor));
  1169. Bindings^.Insert(B);
  1170. Idx:=Bindings^.IndexOf(B);
  1171. Count:=GetLineCount;
  1172. for I:=0 to Count-1 do
  1173. begin
  1174. L:=GetLine(I);
  1175. L^.AddEditorInfo(Idx,AEditor);
  1176. end;
  1177. BindingsChanged;
  1178. end;
  1179. procedure TCustomCodeEditorCore.UnBindEditor(AEditor: PCustomCodeEditor);
  1180. var B: PEditorBinding;
  1181. Count,I: sw_integer;
  1182. L: PCustomLine;
  1183. begin
  1184. B:=SearchBinding(AEditor);
  1185. if Assigned(B) then
  1186. begin
  1187. Count:=GetLineCount;
  1188. for I:=0 to Count-1 do
  1189. begin
  1190. L:=GetLine(I);
  1191. L^.RemoveEditorInfo(AEditor);
  1192. end;
  1193. Bindings^.Free(B);
  1194. BindingsChanged;
  1195. end;
  1196. end;
  1197. function TCustomCodeEditorCore.IsEditorBound(AEditor: PCustomCodeEditor): boolean;
  1198. begin
  1199. IsEditorBound:=SearchBinding(AEditor)<>nil;
  1200. end;
  1201. function TCustomCodeEditorCore.GetBindingCount: sw_integer;
  1202. begin
  1203. GetBindingCount:=Bindings^.Count;
  1204. end;
  1205. function TCustomCodeEditorCore.GetBindingIndex(AEditor: PCustomCodeEditor): sw_integer;
  1206. var B: PEditorBinding;
  1207. begin
  1208. B:=SearchBinding(AEditor);
  1209. GetBindingIndex:=Bindings^.IndexOf(B);
  1210. end;
  1211. function TCustomCodeEditorCore.SearchBinding(AEditor: PCustomCodeEditor): PEditorBinding;
  1212. function SearchEditor(P: PEditorBinding): boolean; {$ifndef FPC}far;{$endif}
  1213. begin
  1214. SearchEditor:=P^.Editor=AEditor;
  1215. end;
  1216. begin
  1217. SearchBinding:=Bindings^.FirstThat(@SearchEditor);
  1218. end;
  1219. function TCustomCodeEditorCore.CanDispose: boolean;
  1220. begin
  1221. CanDispose:=Assigned(Bindings) and (Bindings^.Count=0);
  1222. end;
  1223. function TCustomCodeEditorCore.GetModified: boolean;
  1224. begin
  1225. Abstract;
  1226. GetModified:=true;
  1227. end;
  1228. procedure TCustomCodeEditorCore.SetModified(AModified: boolean);
  1229. begin
  1230. Abstract;
  1231. end;
  1232. function TCustomCodeEditorCore.GetStoreUndo: boolean;
  1233. begin
  1234. Abstract;
  1235. GetStoreUndo:=false;
  1236. end;
  1237. procedure TCustomCodeEditorCore.SetStoreUndo(AStore: boolean);
  1238. begin
  1239. Abstract;
  1240. end;
  1241. function TCustomCodeEditorCore.GetSyntaxCompleted: boolean;
  1242. begin
  1243. Abstract;
  1244. GetSyntaxCompleted:=true;
  1245. end;
  1246. procedure TCustomCodeEditorCore.SetSyntaxCompleted(SC : boolean);
  1247. begin
  1248. Abstract;
  1249. end;
  1250. function TCustomCodeEditorCore.IsClipboard: Boolean;
  1251. function IsClip(P: PEditorBinding): boolean; {$ifndef FPC}far;{$endif}
  1252. begin
  1253. IsClip:=(P^.Editor=Clipboard);
  1254. end;
  1255. begin
  1256. IsClipBoard:=Bindings^.FirstThat(@IsClip)<>nil;
  1257. end;
  1258. function TCustomCodeEditorCore.GetTabSize: integer;
  1259. begin
  1260. Abstract;
  1261. GetTabSize:=0;
  1262. end;
  1263. procedure TCustomCodeEditorCore.SetTabSize(ATabSize: integer);
  1264. begin
  1265. Abstract;
  1266. end;
  1267. procedure TCustomCodeEditorCore.LimitsChanged;
  1268. begin
  1269. if Locked then
  1270. LimitsChangedCalled:=true
  1271. else
  1272. DoLimitsChanged;
  1273. end;
  1274. procedure TCustomCodeEditorCore.ContentsChanged;
  1275. begin
  1276. if Locked then
  1277. ContentsChangedCalled:=true
  1278. else
  1279. DoContentsChanged;
  1280. end;
  1281. procedure TCustomCodeEditorCore.ModifiedChanged;
  1282. begin
  1283. if Locked then
  1284. ModifiedChangedCalled:=true
  1285. else
  1286. DoModifiedChanged;
  1287. end;
  1288. procedure TCustomCodeEditorCore.TabSizeChanged;
  1289. begin
  1290. if Locked then
  1291. TabSizeChangedCalled:=true
  1292. else
  1293. DoTabSizeChanged;
  1294. end;
  1295. procedure TCustomCodeEditorCore.StoreUndoChanged;
  1296. begin
  1297. if Locked then
  1298. StoreUndoChangedCalled:=true
  1299. else
  1300. DoStoreUndoChanged;
  1301. end;
  1302. procedure TCustomCodeEditorCore.BindingsChanged;
  1303. procedure CallIt(P: PEditorBinding); {$ifndef FPC}far;{$endif}
  1304. begin
  1305. P^.Editor^.BindingsChanged;
  1306. end;
  1307. begin
  1308. Bindings^.ForEach(@CallIt);
  1309. end;
  1310. procedure TCustomCodeEditorCore.DoLimitsChanged;
  1311. procedure CallIt(P: PEditorBinding); {$ifndef FPC}far;{$endif}
  1312. begin
  1313. P^.Editor^.DoLimitsChanged;
  1314. end;
  1315. begin
  1316. Bindings^.ForEach(@CallIt);
  1317. end;
  1318. procedure TCustomCodeEditorCore.DoContentsChanged;
  1319. procedure CallIt(P: PEditorBinding); {$ifndef FPC}far;{$endif}
  1320. begin
  1321. P^.Editor^.ContentsChanged;
  1322. end;
  1323. begin
  1324. Bindings^.ForEach(@CallIt);
  1325. end;
  1326. procedure TCustomCodeEditorCore.DoModifiedChanged;
  1327. procedure CallIt(P: PEditorBinding); {$ifndef FPC}far;{$endif}
  1328. begin
  1329. P^.Editor^.ModifiedChanged;
  1330. end;
  1331. begin
  1332. Bindings^.ForEach(@CallIt);
  1333. end;
  1334. procedure TCustomCodeEditorCore.DoTabSizeChanged;
  1335. procedure CallIt(P: PEditorBinding); {$ifndef FPC}far;{$endif}
  1336. begin
  1337. P^.Editor^.TabSizeChanged;
  1338. end;
  1339. begin
  1340. Bindings^.ForEach(@CallIt);
  1341. end;
  1342. procedure TCustomCodeEditorCore.UpdateUndoRedo(cm : word; action : byte);
  1343. procedure CallIt(P: PEditorBinding); {$ifndef FPC}far;{$endif}
  1344. begin
  1345. if (P^.Editor^.State and sfActive)<>0 then
  1346. begin
  1347. P^.Editor^.UpdateUndoRedo(cm,action);
  1348. if cm=cmUndo then
  1349. begin
  1350. P^.Editor^.SetCmdState(UndoCmd,true);
  1351. P^.Editor^.SetCmdState(RedoCmd,false);
  1352. Message(Application,evBroadcast,cmCommandSetChanged,nil);
  1353. end;
  1354. end;
  1355. end;
  1356. begin
  1357. Bindings^.ForEach(@CallIt);
  1358. end;
  1359. procedure TCustomCodeEditorCore.DoStoreUndoChanged;
  1360. procedure CallIt(P: PEditorBinding); {$ifndef FPC}far;{$endif}
  1361. begin
  1362. P^.Editor^.StoreUndoChanged;
  1363. end;
  1364. begin
  1365. Bindings^.ForEach(@CallIt);
  1366. end;
  1367. procedure TCustomCodeEditorCore.DoSyntaxStateChanged;
  1368. procedure CallIt(P: PEditorBinding); {$ifndef FPC}far;{$endif}
  1369. begin
  1370. P^.Editor^.SyntaxStateChanged;
  1371. end;
  1372. begin
  1373. Bindings^.ForEach(@CallIt);
  1374. end;
  1375. function TCustomCodeEditorCore.GetLastVisibleLine : sw_integer;
  1376. var
  1377. y : sw_integer;
  1378. procedure CallIt(P: PEditorBinding); {$ifndef FPC}far;{$endif}
  1379. begin
  1380. if y < P^.Editor^.Delta.Y+P^.Editor^.Size.Y then
  1381. y:=P^.Editor^.Delta.Y+P^.Editor^.Size.Y;
  1382. end;
  1383. begin
  1384. y:=0;
  1385. Bindings^.ForEach(@CallIt);
  1386. GetLastVisibleLine:=y;
  1387. end;
  1388. function TCustomCodeEditorCore.SaveToStream(Editor: PCustomCodeEditor; Stream: PStream): boolean;
  1389. var A,B: TPoint;
  1390. begin
  1391. A.Y:=0; A.X:=0;
  1392. B.Y:=GetLineCount-1;
  1393. if GetLineCount>0 then
  1394. B.X:=length(GetDisplayText(B.Y))
  1395. else
  1396. B.X:=0;
  1397. SaveToStream:=SaveAreaToStream(Editor,Stream,A,B);
  1398. end;
  1399. procedure TCustomCodeEditorCore.ISetLineFlagState(Binding: PEditorBinding; LineNo: sw_integer; Flag: longint; ASet: boolean);
  1400. begin
  1401. Abstract;
  1402. end;
  1403. procedure TCustomCodeEditorCore.IGetDisplayTextFormat(Binding: PEditorBinding; LineNo: sw_integer;var DT,DF:string);
  1404. begin
  1405. Abstract;
  1406. end;
  1407. function TCustomCodeEditorCore.IGetLineFormat(Binding: PEditorBinding; LineNo: sw_integer): string;
  1408. begin
  1409. Abstract;
  1410. IGetLineFormat:='';
  1411. end;
  1412. procedure TCustomCodeEditorCore.ISetLineFormat(Binding: PEditorBinding; LineNo: sw_integer;const S: string);
  1413. begin
  1414. Abstract;
  1415. end;
  1416. function TCustomCodeEditorCore.CharIdxToLinePos(Line,CharIdx: sw_integer): sw_integer;
  1417. var S: string;
  1418. TabSize,CP,RX: sw_integer;
  1419. begin
  1420. S:=GetLineText(Line);
  1421. TabSize:=GetTabSize;
  1422. CP:=1; RX:=0;
  1423. while (CP<=length(S)) and (CP<=CharIdx) do
  1424. begin
  1425. if S[CP]=TAB then
  1426. Inc(RX,GetTabSize-(RX mod TabSize))
  1427. else
  1428. Inc(RX);
  1429. Inc(CP);
  1430. end;
  1431. CharIdxToLinePos:=RX-1;
  1432. end;
  1433. function TCustomCodeEditorCore.LinePosToCharIdx(Line,X: sw_integer): sw_integer;
  1434. var S: string;
  1435. TabSize,CP,RX: sw_integer;
  1436. begin
  1437. TabSize:=GetTabSize;
  1438. S:=GetLineText(Line);
  1439. if S='' then
  1440. CP:=0
  1441. else
  1442. begin
  1443. CP:=0; RX:=0;
  1444. while (RX<=X) and (CP<=length(S)) do
  1445. begin
  1446. Inc(CP);
  1447. if S[CP]=TAB then
  1448. Inc(RX,TabSize-(RX mod TabSize))
  1449. else
  1450. Inc(RX);
  1451. end;
  1452. end;
  1453. LinePosToCharIdx:=CP;
  1454. end;
  1455. function TCustomCodeEditorCore.GetLineCount: sw_integer;
  1456. begin
  1457. Abstract;
  1458. GetLineCount:=0;
  1459. end;
  1460. function TCustomCodeEditorCore.GetLine(LineNo: sw_integer): PCustomLine;
  1461. begin
  1462. Abstract;
  1463. GetLine:=nil;
  1464. end;
  1465. function TCustomCodeEditorCore.GetLineText(LineNo: sw_integer): string;
  1466. begin
  1467. Abstract;
  1468. GetLineText:='';
  1469. end;
  1470. procedure TCustomCodeEditorCore.SetDisplayText(I: sw_integer;const S: string);
  1471. begin
  1472. Abstract;
  1473. end;
  1474. function TCustomCodeEditorCore.GetDisplayText(I: sw_integer): string;
  1475. begin
  1476. Abstract;
  1477. GetDisplayText:='';
  1478. end;
  1479. procedure TCustomCodeEditorCore.SetLineText(I: sw_integer;const S: string);
  1480. begin
  1481. Abstract;
  1482. end;
  1483. procedure TCustomCodeEditorCore.GetDisplayTextFormat(Editor: PCustomCodeEditor; I: sw_integer;var DT,DF:string);
  1484. begin
  1485. IGetDisplayTextFormat(SearchBinding(Editor),I,DT,DF);
  1486. end;
  1487. function TCustomCodeEditorCore.GetLineFormat(Editor: PCustomCodeEditor; I: sw_integer): string;
  1488. begin
  1489. GetLineFormat:=IGetLineFormat(SearchBinding(Editor),I);
  1490. end;
  1491. procedure TCustomCodeEditorCore.SetLineFormat(Editor: PCustomCodeEditor; I: sw_integer; const S: string);
  1492. begin
  1493. ISetLineFormat(SearchBinding(Editor),I,S);
  1494. end;
  1495. procedure TCustomCodeEditorCore.DeleteAllLines;
  1496. begin
  1497. Abstract;
  1498. end;
  1499. procedure TCustomCodeEditorCore.DeleteLine(I: sw_integer);
  1500. begin
  1501. Abstract;
  1502. end;
  1503. procedure TCustomCodeEditorCore.InsertLine(LineNo: sw_integer; const S: string);
  1504. begin
  1505. Abstract;
  1506. end;
  1507. procedure TCustomCodeEditorCore.AddLine(const S: string);
  1508. begin
  1509. Abstract;
  1510. end;
  1511. procedure TCustomCodeEditorCore.GetContent(ALines: PUnsortedStringCollection);
  1512. begin
  1513. Abstract;
  1514. end;
  1515. procedure TCustomCodeEditorCore.SetContent(ALines: PUnsortedStringCollection);
  1516. begin
  1517. Abstract;
  1518. end;
  1519. function TCustomCodeEditorCore.Locked: boolean;
  1520. begin
  1521. Locked:=LockFlag>0;
  1522. end;
  1523. procedure TCustomCodeEditorCore.Lock(AEditor: PCustomCodeEditor);
  1524. begin
  1525. Inc(LockFlag);
  1526. end;
  1527. procedure TCustomCodeEditorCore.UnLock(AEditor: PCustomCodeEditor);
  1528. begin
  1529. {$ifdef DEBUG}
  1530. if LockFlag=0 then
  1531. Bug('negative lockflag',nil)
  1532. else
  1533. {$endif DEBUG}
  1534. Dec(LockFlag);
  1535. if (LockFlag>0) then
  1536. Exit;
  1537. if LimitsChangedCalled then
  1538. begin
  1539. DoLimitsChanged;
  1540. LimitsChangedCalled:=false;
  1541. end;
  1542. if ModifiedChangedCalled then
  1543. begin
  1544. DoModifiedChanged;
  1545. ModifiedChangedCalled:=false;
  1546. end;
  1547. if TabSizeChangedCalled then
  1548. begin
  1549. DoTabSizeChanged;
  1550. TabSizeChangedCalled:=false;
  1551. end;
  1552. if StoreUndoChangedCalled then
  1553. begin
  1554. DoStoreUndoChanged;
  1555. StoreUndoChangedCalled:=false;
  1556. end;
  1557. if ContentsChangedCalled then
  1558. begin
  1559. DoContentsChanged;
  1560. ContentsChangedCalled:=false;
  1561. end;
  1562. end;
  1563. function TCustomCodeEditorCore.UpdateAttrs(FromLine: sw_integer; Attrs: byte): sw_integer;
  1564. procedure CallIt(P: PEditorBinding); {$ifndef FPC}far;{$endif}
  1565. begin
  1566. DoUpdateAttrs(P^.Editor,FromLine,Attrs);
  1567. end;
  1568. begin
  1569. Bindings^.ForEach(@CallIt);
  1570. end;
  1571. function TCustomCodeEditorCore.UpdateAttrsRange(FromLine, ToLine: sw_integer; Attrs: byte): sw_integer;
  1572. procedure CallIt(P: PEditorBinding); {$ifndef FPC}far;{$endif}
  1573. begin
  1574. DoUpdateAttrsRange(P^.Editor,FromLine,ToLine,Attrs);
  1575. end;
  1576. begin
  1577. Bindings^.ForEach(@CallIt);
  1578. end;
  1579. function TCustomCodeEditorCore.DoUpdateAttrs(Editor: PCustomCodeEditor; FromLine: sw_integer; Attrs: byte): sw_integer;
  1580. type
  1581. TCharClass = (ccWhiteSpace,ccTab,ccAlpha,ccNumber,ccRealNumber,ccHash,ccSymbol);
  1582. var
  1583. SymbolIndex: Sw_integer;
  1584. CurrentCommentType : Byte;
  1585. FirstCC,LastCC: TCharClass;
  1586. InAsm,InComment,InSingleLineComment,InDirective,InString: boolean;
  1587. X,ClassStart: Sw_integer;
  1588. SymbolConcat: string;
  1589. LineText,Format: string;
  1590. function MatchSymbol(const What, S: string): boolean;
  1591. var Match: boolean;
  1592. begin
  1593. Match:=false;
  1594. if length(What)>=length(S) then
  1595. if copy(What,1+length(What)-length(S),length(S))=S then
  1596. Match:=true;
  1597. MatchSymbol:=Match;
  1598. end;
  1599. var MatchedSymbol: boolean;
  1600. MatchingSymbol: string;
  1601. type TPartialType = (pmNone,pmLeft,pmRight,pmAny);
  1602. function MatchesAnySpecSymbol(What: string; SClass: TSpecSymbolClass; PartialMatch: TPartialType;
  1603. CaseInsensitive: boolean): boolean;
  1604. var S: string;
  1605. I: Sw_integer;
  1606. Match,Found: boolean;
  1607. begin
  1608. Found:=false;
  1609. if CaseInsensitive then
  1610. What:=UpcaseStr(What);
  1611. if What<>'' then
  1612. for I:=1 to Editor^.GetSpecSymbolCount(SClass) do
  1613. begin
  1614. SymbolIndex:=I;
  1615. S:=Editor^.GetSpecSymbol(SClass,I-1);
  1616. if (length(What)<length(S)) or
  1617. ((PartialMatch=pmNone) and (length(S)<>length(What)))
  1618. then
  1619. Match:=false
  1620. else
  1621. begin
  1622. if CaseInsensitive then
  1623. S:=UpcaseStr(S);
  1624. case PartialMatch of
  1625. pmNone : Match:=What=S;
  1626. pmRight:
  1627. Match:=copy(What,length(What)-length(S)+1,length(S))=S;
  1628. else Match:=MatchSymbol(What,S);
  1629. end;
  1630. end;
  1631. if Match then
  1632. begin
  1633. MatchingSymbol:=S; Found:=true; Break;
  1634. end;
  1635. end;
  1636. MatchedSymbol:=MatchedSymbol or Found;
  1637. MatchesAnySpecSymbol:=Found;
  1638. end;
  1639. function IsCommentPrefix: boolean;
  1640. begin
  1641. IsCommentPrefix:=MatchesAnySpecSymbol(SymbolConcat,ssCommentPrefix,pmLeft,false);
  1642. end;
  1643. function IsSingleLineCommentPrefix: boolean;
  1644. begin
  1645. IsSingleLineCommentPrefix:=MatchesAnySpecSymbol(SymbolConcat,ssCommentSingleLinePrefix,pmLeft,false);
  1646. end;
  1647. function IsCommentSuffix: boolean;
  1648. begin
  1649. IsCommentSuffix:=(MatchesAnySpecSymbol(SymbolConcat,ssCommentSuffix,pmRight,false))
  1650. and (CurrentCommentType=SymbolIndex);
  1651. end;
  1652. function IsStringPrefix: boolean;
  1653. begin
  1654. IsStringPrefix:=MatchesAnySpecSymbol(SymbolConcat,ssStringPrefix,pmLeft,false);
  1655. end;
  1656. function IsStringSuffix: boolean;
  1657. begin
  1658. IsStringSuffix:=MatchesAnySpecSymbol(SymbolConcat,ssStringSuffix,pmRight,false);
  1659. end;
  1660. function IsDirectivePrefix: boolean;
  1661. begin
  1662. IsDirectivePrefix:=MatchesAnySpecSymbol(SymbolConcat,ssDirectivePrefix,pmLeft,false);
  1663. end;
  1664. function IsDirectiveSuffix: boolean;
  1665. begin
  1666. IsDirectiveSuffix:=MatchesAnySpecSymbol(SymbolConcat,ssDirectiveSuffix,pmRight,false);
  1667. end;
  1668. function IsAsmPrefix(const WordS: string): boolean;
  1669. begin
  1670. IsAsmPrefix:=MatchesAnySpecSymbol(WordS,ssAsmPrefix,pmNone,true);
  1671. end;
  1672. function IsAsmSuffix(const WordS: string): boolean;
  1673. begin
  1674. IsAsmSuffix:=MatchesAnySpecSymbol(WordS,ssAsmSuffix,pmNone,true);
  1675. end;
  1676. function GetCharClass(C: char): TCharClass;
  1677. var CC: TCharClass;
  1678. begin
  1679. if C in WhiteSpaceChars then CC:=ccWhiteSpace else
  1680. if C in TabChars then CC:=ccTab else
  1681. if C in HashChars then CC:=ccHash else
  1682. if C in AlphaChars then CC:=ccAlpha else
  1683. if C in NumberChars then CC:=ccNumber else
  1684. if (LastCC=ccNumber) and (C in RealNumberChars) then
  1685. begin
  1686. if (C='.') then
  1687. begin
  1688. if (LineText[X+1]='.') then
  1689. cc:=ccSymbol
  1690. else
  1691. CC:=ccRealNumber
  1692. end
  1693. else
  1694. cc:=ccrealnumber;
  1695. end else
  1696. CC:=ccSymbol;
  1697. GetCharClass:=CC;
  1698. end;
  1699. procedure FormatWord(SClass: TCharClass; StartX:Sw_integer;EndX: Sw_integer);
  1700. var
  1701. C: byte;
  1702. WordS: string;
  1703. begin
  1704. C:=0;
  1705. WordS:=copy(LineText,StartX,EndX-StartX+1);
  1706. if IsAsmSuffix(WordS) and (InAsm=true) and (InComment=false) and
  1707. (InString=false) and (InDirective=false) then InAsm:=false;
  1708. if InDirective then C:=coDirectiveColor else
  1709. if InComment then C:=coCommentColor else
  1710. if InString then C:=coStringColor else
  1711. if InAsm then C:=coAssemblerColor else
  1712. case SClass of
  1713. ccWhiteSpace : C:=coWhiteSpaceColor;
  1714. ccTab : C:=coTabColor;
  1715. ccNumber :
  1716. if copy(WordS,1,1)='$' then
  1717. C:=coHexNumberColor
  1718. else
  1719. C:=coNumberColor;
  1720. ccHash :
  1721. C:=coStringColor;
  1722. ccSymbol :
  1723. C:=coSymbolColor;
  1724. ccAlpha :
  1725. begin
  1726. if Editor^.IsReservedWord(WordS) then
  1727. C:=coReservedWordColor
  1728. else
  1729. C:=coIdentifierColor;
  1730. end;
  1731. end;
  1732. if EndX+1>=StartX then
  1733. FillChar(Format[StartX],EndX+1-StartX,C);
  1734. if IsAsmPrefix(WordS) and
  1735. (InAsm=false) and (InComment=false) and (InDirective=false) then
  1736. InAsm:=true;
  1737. end;
  1738. procedure ProcessChar(C: char);
  1739. var CC: TCharClass;
  1740. EX: Sw_integer;
  1741. begin
  1742. CC:=GetCharClass(C);
  1743. if ClassStart=X then
  1744. FirstCC:=CC;
  1745. if ( (CC<>LastCC) and
  1746. (
  1747. ((FirstCC=ccNumber) and (CC<>ccRealNumber)) or
  1748. (((CC<>ccAlpha) or (LastCC<>ccNumber) ) and
  1749. ( (CC<>ccNumber) or (LastCC<>ccAlpha) ) and
  1750. ( (CC<>ccNumber) or (LastCC<>ccHash) ) and
  1751. ( (CC<>ccRealNumber) or (LastCC<>ccNumber))
  1752. ))) or
  1753. (X>length(LineText)) or (CC=ccSymbol) then
  1754. begin
  1755. MatchedSymbol:=false;
  1756. EX:=X-1;
  1757. if (CC=ccSymbol) then
  1758. begin
  1759. if length(SymbolConcat)>=High(SymbolConcat) then
  1760. Delete(SymbolConcat,1,1);
  1761. SymbolConcat:=SymbolConcat+C;
  1762. end;
  1763. case CC of
  1764. ccSymbol :
  1765. if IsCommentSuffix and (InComment) then
  1766. Inc(EX) else
  1767. if IsStringSuffix and (InString) then
  1768. Inc(EX) else
  1769. if IsDirectiveSuffix and (InDirective) then
  1770. Inc(EX);
  1771. end;
  1772. if (C='$') and (MatchedSymbol=false) and (IsDirectivePrefix=false) then
  1773. CC:=ccNumber;
  1774. if CC<>ccSymbol then SymbolConcat:='';
  1775. FormatWord(LastCC,ClassStart,EX);
  1776. ClassStart:=EX+1;
  1777. case CC of
  1778. ccAlpha : ;
  1779. ccNumber :
  1780. if (LastCC<>ccAlpha) then;
  1781. ccSymbol :
  1782. if IsDirectivePrefix and {(InComment=false) and }(InDirective=false) then
  1783. begin InDirective:=true; InComment:=false; Dec(ClassStart,length(MatchingSymbol)-1); end else
  1784. if IsDirectiveSuffix and (InComment=false) and (InDirective=true) then
  1785. InDirective:=false else
  1786. if IsCommentPrefix and (InComment=false) and (InString=false) then
  1787. begin
  1788. InComment:=true;
  1789. CurrentCommentType:=SymbolIndex;
  1790. InSingleLineComment:=IsSingleLineCommentPrefix;
  1791. {InString:=false; }
  1792. Dec(ClassStart,length(MatchingSymbol)-1);
  1793. end
  1794. else
  1795. if IsCommentSuffix and (InComment) then
  1796. begin InComment:=false; InString:=false; end else
  1797. if IsStringPrefix and (InComment=false) and (InString=false) then
  1798. begin InString:=true; Dec(ClassStart,length(MatchingSymbol)-1); end else
  1799. if IsStringSuffix and (InComment=false) and (InString=true) then
  1800. InString:=false;
  1801. end;
  1802. if MatchedSymbol and (InComment=false) then
  1803. SymbolConcat:='';
  1804. LastCC:=CC;
  1805. end;
  1806. end;
  1807. var CurLine: Sw_integer;
  1808. Line,NextLine,PrevLine,OldLine: PCustomLine;
  1809. B: PEditorBinding;
  1810. PrevLI,LI,NextLI: PEditorLineInfo;
  1811. begin
  1812. B:=SearchBinding(Editor);
  1813. if (not Editor^.IsFlagSet(efSyntaxHighlight)) or (FromLine>=GetLineCount) then
  1814. begin
  1815. SetLineFormat(Editor,FromLine,'');
  1816. DoUpdateAttrs:=GetLineCount;
  1817. {$ifdef TEST_PARTIAL_SYNTAX}
  1818. LastSyntaxedLine:=GetLineCount;
  1819. if not SyntaxComplete then
  1820. begin
  1821. SyntaxComplete:=true;
  1822. DoSyntaxStateChanged;
  1823. end;
  1824. (* { no Idle necessary }
  1825. EventMask:=EventMask and not evIdle;*)
  1826. {$endif TEST_PARTIAL_SYNTAX}
  1827. Editor^.SyntaxStateChanged;
  1828. Exit;
  1829. end;
  1830. {$ifdef TEST_PARTIAL_SYNTAX}
  1831. If Editor^.IsFlagSet(efSyntaxHighlight) and (LastSyntaxedLine<FromLine)
  1832. and (FromLine<GetLineCount) then
  1833. CurLine:=LastSyntaxedLine
  1834. else
  1835. {$endif TEST_PARTIAL_SYNTAX}
  1836. CurLine:=FromLine;
  1837. if CurLine>0 then
  1838. PrevLine:=GetLine(CurLine-1)
  1839. else
  1840. PrevLine:=nil;
  1841. repeat
  1842. Line:=GetLine(CurLine);
  1843. if Assigned(PrevLine) then PrevLI:=PrevLine^.GetEditorInfo(Editor) else PrevLI:=nil;
  1844. if Assigned(Line) then LI:=Line^.GetEditorInfo(Editor) else LI:=nil;
  1845. InSingleLineComment:=false;
  1846. if PrevLI<>nil then
  1847. begin
  1848. InAsm:=PrevLI^.EndsWithAsm;
  1849. InComment:=PrevLI^.EndsWithComment and not PrevLI^.EndsInSingleLineComment;
  1850. CurrentCommentType:=PrevLI^.EndCommentType;
  1851. InDirective:=PrevLI^.EndsWithDirective;
  1852. end
  1853. else
  1854. begin
  1855. InAsm:=false;
  1856. InComment:=false;
  1857. CurrentCommentType:=0;
  1858. InDirective:=false;
  1859. end;
  1860. OldLine:=Line;
  1861. LI^.BeginsWithAsm:=InAsm;
  1862. LI^.BeginsWithComment:=InComment;
  1863. LI^.BeginsWithDirective:=InDirective;
  1864. LI^.BeginCommentType:=CurrentCommentType;
  1865. LineText:=GetLineText(CurLine);
  1866. Format:=CharStr(chr(coTextColor),length(LineText));
  1867. LastCC:=ccWhiteSpace;
  1868. ClassStart:=1;
  1869. SymbolConcat:='';
  1870. InString:=false;
  1871. if LineText<>'' then
  1872. begin
  1873. for X:=1 to length(LineText) do
  1874. ProcessChar(LineText[X]);
  1875. Inc(X);
  1876. ProcessChar(' ');
  1877. end;
  1878. SetLineFormat(Editor,CurLine,Format);
  1879. LI^.EndsWithAsm:=InAsm;
  1880. LI^.EndsWithComment:=InComment;
  1881. LI^.EndsInSingleLineComment:=InSingleLineComment;
  1882. LI^.EndCommentType:=CurrentCommentType;
  1883. LI^.EndsWithDirective:=InDirective;
  1884. Inc(CurLine);
  1885. if CurLine>=GetLineCount then
  1886. Break;
  1887. NextLine:=GetLine(CurLine);
  1888. if Assigned(NextLine) then NextLI:=NextLine^.GetEditorInfo(Editor) else NextLI:=nil;
  1889. if ((Attrs and attrForceFull)=0) then
  1890. if { Why should we go
  1891. (InAsm=false) and (NextLine^.BeginsWithAsm=false) and
  1892. (InComment=false) and (NextLine^.BeginsWithComment=false) and
  1893. (InDirective=false) and (NextLine^.BeginsWithDirective=false) and
  1894. OldLine = Line so this is nonsense
  1895. (OldLine^.EndsWithComment=Line^.EndsWithComment) and
  1896. (OldLine^.EndsWithAsm=Line^.EndsWithAsm) and
  1897. (OldLine^.EndsWithDirective=Line^.EndsWithDirective) and }
  1898. {$ifdef TEST_PARTIAL_SYNTAX}
  1899. (CurLine>FromLine) and
  1900. {$endif TEST_PARTIAL_SYNTAX}
  1901. (NextLI^.BeginsWithAsm=LI^.EndsWithAsm) and
  1902. (NextLI^.BeginsWithComment=LI^.EndsWithComment) and
  1903. (NextLI^.BeginsWithDirective=LI^.EndsWithDirective) and
  1904. (NextLI^.BeginCommentType=LI^.EndCommentType) and
  1905. (NextLI^.Format<>nil) then
  1906. Break;
  1907. {$ifdef TEST_PARTIAL_SYNTAX}
  1908. if (CurLine<GetLineCount) and
  1909. (CurLine>FromLine) and
  1910. ((Attrs and attrForceFull)=0) and
  1911. (CurLine>GetLastVisibleLine) then
  1912. begin
  1913. If SyntaxComplete then
  1914. begin
  1915. SyntaxComplete:=false;
  1916. DoSyntaxStateChanged;
  1917. end;
  1918. LastSyntaxedLine:=CurLine-1;
  1919. break;
  1920. end;
  1921. {$endif TEST_PARTIAL_SYNTAX}
  1922. PrevLine:=Line;
  1923. until false;
  1924. DoUpdateAttrs:=CurLine;
  1925. {$ifdef TEST_PARTIAL_SYNTAX}
  1926. If LastSyntaxedLine<CurLine-1 then
  1927. LastSyntaxedLine:=CurLine-1;
  1928. if CurLine=GetLineCount then
  1929. begin
  1930. SyntaxComplete:=true;
  1931. DoSyntaxStateChanged;
  1932. end;
  1933. {$endif TEST_PARTIAL_SYNTAX}
  1934. end;
  1935. function TCustomCodeEditorCore.DoUpdateAttrsRange(Editor: PCustomCodeEditor; FromLine, ToLine: sw_integer;
  1936. Attrs: byte): sw_integer;
  1937. var Line: Sw_integer;
  1938. begin
  1939. Lock(Editor);
  1940. Line:=FromLine;
  1941. repeat
  1942. Line:=DoUpdateAttrs(Editor,Line,Attrs);
  1943. until (Line>=GetLineCount) or (Line>ToLine);
  1944. DoUpdateAttrsRange:=Line;
  1945. Unlock(Editor);
  1946. end;
  1947. procedure TCustomCodeEditorCore.AddAction(AAction: byte; AStartPos, AEndPos: TPoint; AText: string);
  1948. begin
  1949. Abstract;
  1950. end;
  1951. procedure TCustomCodeEditorCore.AddGroupedAction(AAction : byte);
  1952. begin
  1953. Abstract;
  1954. end;
  1955. procedure TCustomCodeEditorCore.CloseGroupedAction(AAction : byte);
  1956. begin
  1957. Abstract;
  1958. end;
  1959. function TCustomCodeEditorCore.GetUndoActionCount: sw_integer;
  1960. begin
  1961. Abstract;
  1962. GetUndoActionCount:=0;
  1963. end;
  1964. function TCustomCodeEditorCore.GetRedoActionCount: sw_integer;
  1965. begin
  1966. Abstract;
  1967. GetRedoActionCount:=0;
  1968. end;
  1969. destructor TCustomCodeEditorCore.Done;
  1970. begin
  1971. {$ifdef DEBUG}
  1972. if Bindings^.Count>0 then
  1973. ErrorBox('Internal error: there are still '+IntToStr(Bindings^.Count)+' editors '+
  1974. 'registered at TCodeEditorCode.Done!!!',nil);
  1975. {$endif}
  1976. if Assigned(Bindings) then Dispose(Bindings, Done); Bindings:=nil;
  1977. inherited Done;
  1978. end;
  1979. procedure TCustomCodeEditor.Lock;
  1980. begin
  1981. Inc(LockFlag);
  1982. end;
  1983. procedure TCustomCodeEditor.UnLock;
  1984. begin
  1985. {$ifdef DEBUG}
  1986. if lockflag=0 then
  1987. Bug('negative lockflag',nil)
  1988. else
  1989. {$endif DEBUG}
  1990. Dec(LockFlag);
  1991. if (LockFlag>0) then
  1992. Exit;
  1993. if DrawCalled then
  1994. DrawView;
  1995. If DrawCursorCalled then
  1996. Begin
  1997. DrawCursor;
  1998. DrawCursorCalled:=false;
  1999. End;
  2000. end;
  2001. procedure TCustomCodeEditor.DrawIndicator;
  2002. begin
  2003. { Abstract }
  2004. end;
  2005. procedure TCustomCodeEditor.AdjustSelectionPos(CurPosX, CurPosY: sw_integer; DeltaX, DeltaY: sw_integer);
  2006. var CP: TPoint;
  2007. begin
  2008. if ValidBlock=false then Exit;
  2009. CP.X:=CurPosX; CP.Y:=CurPosY;
  2010. if (PosToOfsP(SelStart)<=PosToOfsP(CP)) and (PosToOfsP(CP)<PosToOfsP(SelEnd)) then
  2011. begin
  2012. { CurPos is IN selection }
  2013. Inc(SelEnd.Y,DeltaY);
  2014. if (CP.Y=SelEnd.Y) and
  2015. ((SelStart.Y<>SelEnd.Y) or (SelStart.X<=CP.X)) and
  2016. (CP.X<=SelEnd.X) then
  2017. Inc(SelEnd.X,DeltaX);
  2018. SelectionChanged;
  2019. end
  2020. else
  2021. if (PosToOfsP(CP)<=PosToOfsP(SelStart)) then
  2022. begin
  2023. { CurPos is BEFORE selection }
  2024. if (CP.Y=SelStart.Y) and (CP.Y=SelEnd.Y) and (DeltaY<0) then
  2025. begin
  2026. SelStart:=CurPos; SelEnd:=CurPos;
  2027. end
  2028. else
  2029. if (CP.Y=SelStart.Y) then
  2030. begin
  2031. if CP.X<SelStart.X then
  2032. Inc(SelStart.X,DeltaX);
  2033. end;
  2034. { else}
  2035. begin
  2036. Inc(SelStart.Y,DeltaY);
  2037. Inc(SelEnd.Y,DeltaY);
  2038. end;
  2039. if SelEnd.Y=CurPos.Y then Inc(SelEnd.X,DeltaX);
  2040. SelectionChanged;
  2041. end
  2042. else
  2043. begin
  2044. { CurPos is AFTER selection }
  2045. { actually we don't have to do anything here }
  2046. end;
  2047. end;
  2048. function TCustomCodeEditor.GetFlags: longint;
  2049. begin
  2050. { Abstract }
  2051. GetFlags:=0;
  2052. end;
  2053. procedure TCustomCodeEditor.SetFlags(AFlags: longint);
  2054. begin
  2055. { Abstract }
  2056. end;
  2057. function TCustomCodeEditor.GetModified: boolean;
  2058. begin
  2059. { Abstract }
  2060. GetModified:=true;
  2061. end;
  2062. procedure TCustomCodeEditor.SetModified(AModified: boolean);
  2063. begin
  2064. { Abstract }
  2065. end;
  2066. function TCustomCodeEditor.GetStoreUndo: boolean;
  2067. begin
  2068. { Abstract }
  2069. GetStoreUndo:=false;
  2070. end;
  2071. procedure TCustomCodeEditor.SetStoreUndo(AStore: boolean);
  2072. begin
  2073. { Abstract }
  2074. end;
  2075. function TCustomCodeEditor.GetSyntaxCompleted: boolean;
  2076. begin
  2077. { Abstract }
  2078. GetSyntaxCompleted:=true;
  2079. end;
  2080. procedure TCustomCodeEditor.SetSyntaxCompleted(SC : boolean);
  2081. begin
  2082. { Abstract }
  2083. end;
  2084. function TCustomCodeEditor.GetLastSyntaxedLine: sw_integer;
  2085. begin
  2086. Abstract;
  2087. GetLastSyntaxedLine:=0;
  2088. end;
  2089. procedure TCustomCodeEditor.SetLastSyntaxedLine(ALine: sw_integer);
  2090. begin
  2091. Abstract;
  2092. end;
  2093. function TCustomCodeEditor.IsFlagSet(AFlag: longint): boolean;
  2094. begin
  2095. IsFlagSet:=(GetFlags and AFlag)=AFlag;
  2096. end;
  2097. function TCustomCodeEditor.GetTabSize: integer;
  2098. begin
  2099. { Abstract }
  2100. GetTabSize:=5;
  2101. end;
  2102. procedure TCustomCodeEditor.SetTabSize(ATabSize: integer);
  2103. begin
  2104. { Abstract }
  2105. end;
  2106. function TCustomCodeEditor.IsReadOnly: boolean;
  2107. begin
  2108. { Abstract }
  2109. IsReadOnly:=false;
  2110. end;
  2111. function TCustomCodeEditor.IsClipboard: Boolean;
  2112. begin
  2113. { Abstract }
  2114. IsClipboard:=false;
  2115. end;
  2116. function TCustomCodeEditor.GetLineCount: sw_integer;
  2117. begin
  2118. Abstract;
  2119. GetLineCount:=0;
  2120. end;
  2121. function TCustomCodeEditor.GetLine(LineNo: sw_integer): PCustomLine;
  2122. begin
  2123. Abstract;
  2124. GetLine:=nil;
  2125. end;
  2126. function TCustomCodeEditor.CharIdxToLinePos(Line,CharIdx: sw_integer): sw_integer;
  2127. begin
  2128. Abstract;
  2129. CharIdxToLinePos:=0;
  2130. end;
  2131. function TCustomCodeEditor.LinePosToCharIdx(Line,X: sw_integer): sw_integer;
  2132. begin
  2133. Abstract;
  2134. LinePosToCharIdx:=0;
  2135. end;
  2136. function TCustomCodeEditor.GetLineText(I: sw_integer): string;
  2137. begin
  2138. Abstract;
  2139. GetLineText:='';
  2140. end;
  2141. procedure TCustomCodeEditor.SetDisplayText(I: sw_integer;const S: string);
  2142. begin
  2143. Abstract;
  2144. end;
  2145. function TCustomCodeEditor.GetDisplayText(I: sw_integer): string;
  2146. begin
  2147. Abstract;
  2148. GetDisplayText:='';
  2149. end;
  2150. procedure TCustomCodeEditor.SetLineText(I: sw_integer;const S: string);
  2151. begin
  2152. Abstract;
  2153. end;
  2154. procedure TCustomCodeEditor.GetDisplayTextFormat(I: sw_integer;var DT,DF:string);
  2155. begin
  2156. Abstract;
  2157. end;
  2158. function TCustomCodeEditor.GetLineFormat(I: sw_integer): string;
  2159. begin
  2160. { Abstract }
  2161. GetLineFormat:='';
  2162. end;
  2163. procedure TCustomCodeEditor.SetLineFormat(I: sw_integer;const S: string);
  2164. begin
  2165. { Abstract }
  2166. end;
  2167. procedure TCustomCodeEditor.DeleteAllLines;
  2168. begin
  2169. Abstract;
  2170. end;
  2171. procedure TCustomCodeEditor.DeleteLine(I: sw_integer);
  2172. begin
  2173. Abstract;
  2174. end;
  2175. procedure TCustomCodeEditor.InsertLine(LineNo: sw_integer; const S: string);
  2176. begin
  2177. Abstract;
  2178. end;
  2179. procedure TCustomCodeEditor.AddLine(const S: string);
  2180. begin
  2181. Abstract;
  2182. end;
  2183. function TCustomCodeEditor.GetErrorMessage: string;
  2184. begin
  2185. Abstract;
  2186. GetErrorMessage:='';
  2187. end;
  2188. procedure TCustomCodeEditor.SetErrorMessage(const S: string);
  2189. begin
  2190. Abstract;
  2191. end;
  2192. procedure TCustomCodeEditor.GetContent(ALines: PUnsortedStringCollection);
  2193. begin
  2194. Abstract;
  2195. end;
  2196. procedure TCustomCodeEditor.SetContent(ALines: PUnsortedStringCollection);
  2197. begin
  2198. Abstract;
  2199. end;
  2200. function TCustomCodeEditor.LoadFromStream(Stream: PStream): boolean;
  2201. begin
  2202. Abstract;
  2203. LoadFromStream:=false;
  2204. end;
  2205. function TCustomCodeEditor.SaveToStream(Stream: PStream): boolean;
  2206. var A,B: TPoint;
  2207. begin
  2208. A.Y:=0; A.X:=0;
  2209. B.Y:=GetLineCount-1;
  2210. if GetLineCount>0 then
  2211. B.X:=length(GetDisplayText(B.Y))
  2212. else
  2213. B.X:=0;
  2214. SaveToStream:=SaveAreaToStream(Stream,A,B);
  2215. end;
  2216. function TCustomCodeEditor.SaveAreaToStream(Stream: PStream; StartP,EndP: TPoint): boolean;
  2217. begin
  2218. Abstract;
  2219. SaveAreaToStream:=false;
  2220. end;
  2221. function TCustomCodeEditor.InsertFrom(Editor: PCustomCodeEditor): Boolean;
  2222. var OK: boolean;
  2223. LineDelta,LineCount: Sw_integer;
  2224. StartPos,DestPos,BPos,EPos: TPoint;
  2225. LineStartX,LineEndX: Sw_integer;
  2226. S,OrigS,AfterS: string;
  2227. VerticalBlock: boolean;
  2228. SEnd: TPoint;
  2229. begin
  2230. if Editor^.IsFlagSet(efVerticalBlocks) then
  2231. begin
  2232. NotImplemented;
  2233. Exit;
  2234. end;
  2235. Lock;
  2236. { every data in the clipboard gets a new line }
  2237. if (Clipboard=@Self) and (CurPos.X>0) then
  2238. InsertNewLine;
  2239. OK:=(Editor^.SelStart.X<>Editor^.SelEnd.X) or (Editor^.SelStart.Y<>Editor^.SelEnd.Y);
  2240. if OK then
  2241. begin
  2242. StartPos:=CurPos; DestPos:=CurPos;
  2243. EPos:=CurPos;
  2244. VerticalBlock:=Editor^.IsFlagSet(efVerticalBlocks);
  2245. LineDelta:=0; LineCount:=(Editor^.SelEnd.Y-Editor^.SelStart.Y)+1;
  2246. OK:=GetLineCount<MaxLineCount;
  2247. OrigS:=GetDisplayText(DestPos.Y);
  2248. AfterS:=Copy(OrigS,DestPos.X+1,255);
  2249. while OK and (LineDelta<LineCount) do
  2250. begin
  2251. if (LineDelta>0) and (VerticalBlock=false) then
  2252. begin
  2253. InsertLine(DestPos.Y,'');
  2254. BPos.X:=0;BPos.Y:=DestPos.Y;
  2255. EPOS.X:=0;EPos.Y:=DestPos.Y;
  2256. AddAction(eaInsertLine,BPos,EPos,'');
  2257. LimitsChanged;
  2258. end;
  2259. if (LineDelta=0) or VerticalBlock then
  2260. LineStartX:=Editor^.SelStart.X
  2261. else
  2262. LineStartX:=0;
  2263. if (LineDelta=LineCount-1) or VerticalBlock then
  2264. LineEndX:=Editor^.SelEnd.X-1
  2265. else
  2266. LineEndX:=255;
  2267. if LineEndX<LineStartX then
  2268. S:=''
  2269. else if VerticalBlock then
  2270. S:=RExpand(copy(Editor^.GetLineText(Editor^.SelStart.Y+LineDelta),LineStartX+1,LineEndX-LineStartX+1),
  2271. Min(LineEndX-LineStartX+1,255))
  2272. else
  2273. S:=copy(Editor^.GetLineText(Editor^.SelStart.Y+LineDelta),LineStartX+1,LineEndX-LineStartX+1);
  2274. if VerticalBlock=false then
  2275. begin
  2276. If LineDelta>0 then
  2277. OrigS:='';
  2278. if LineDelta=LineCount-1 then
  2279. begin
  2280. SetLineText(DestPos.Y,RExpand(copy(OrigS,1,DestPos.X),DestPos.X)+S+AfterS);
  2281. BPos.X:=DestPos.X;BPos.Y:=DestPos.Y;
  2282. EPOS.X:=DestPos.X+Length(S);EPos.Y:=DestPos.Y;
  2283. AddAction(eaInsertText,BPos,EPos,S);
  2284. end
  2285. else
  2286. begin
  2287. SetLineText(DestPos.Y,RExpand(copy(OrigS,1,DestPos.X),DestPos.X)+S);
  2288. BPos.X:=DestPos.X;BPos.Y:=DestPos.Y;
  2289. EPOS.X:=DestPos.X+Length(S);EPos.Y:=DestPos.Y;
  2290. AddAction(eaInsertText,BPos,EPos,S);
  2291. end;
  2292. if LineDelta=LineCount-1 then
  2293. begin
  2294. SEnd.Y:=DestPos.Y;
  2295. SEnd.X:=DestPos.X+length(S);
  2296. end
  2297. else
  2298. begin
  2299. Inc(DestPos.Y);
  2300. DestPos.X:=0;
  2301. end;
  2302. end
  2303. else { if VerticalBlock=false then .. else }
  2304. begin
  2305. { this is not yet implemented !! PM }
  2306. S:=RExpand(S,LineEndX-LineStartX+1);
  2307. end;
  2308. Inc(LineDelta);
  2309. OK:=GetLineCount<MaxLineCount;
  2310. end;
  2311. if OK=false then EditorDialog(edTooManyLines,nil);
  2312. { mainly to force eaMove insertion }
  2313. if not IsClipboard then
  2314. SetCurPtr(EPos.X,EPos.Y);
  2315. SetCurPtr(StartPos.X,StartPos.Y);
  2316. UpdateAttrs(StartPos.Y,attrAll);
  2317. SetModified(true);
  2318. LimitsChanged;
  2319. SetSelection(CurPos,SEnd);
  2320. if IsClipboard then
  2321. begin
  2322. Inc(DestPos.X,length(S));
  2323. SetCurPtr(DestPos.X,DestPos.Y);
  2324. end;
  2325. DrawView;
  2326. end;
  2327. UnLock;
  2328. InsertFrom:=OK;
  2329. end;
  2330. function TCustomCodeEditor.InsertText(const S: string): Boolean;
  2331. var I: sw_integer;
  2332. OldPos: TPoint;
  2333. HoldUndo : boolean;
  2334. begin
  2335. Lock;
  2336. OldPos:=CurPos;
  2337. HoldUndo:=GetStoreUndo;
  2338. SetStoreUndo(false);
  2339. for I:=1 to length(S) do
  2340. AddChar(S[I]);
  2341. InsertText:=true;
  2342. SetStoreUndo(HoldUndo);
  2343. AddAction(eaInsertText,OldPos,CurPos,S);
  2344. UnLock;
  2345. end;
  2346. procedure TCustomCodeEditor.ModifiedChanged;
  2347. begin
  2348. { Abstract }
  2349. end;
  2350. procedure TCustomCodeEditor.PositionChanged;
  2351. begin
  2352. { Abstract }
  2353. end;
  2354. procedure TCustomCodeEditor.TabSizeChanged;
  2355. begin
  2356. { Abstract }
  2357. end;
  2358. procedure TCustomCodeEditor.SyntaxStateChanged;
  2359. begin
  2360. { Abstract }
  2361. end;
  2362. procedure TCustomCodeEditor.StoreUndoChanged;
  2363. begin
  2364. { Abstract }
  2365. end;
  2366. function TCustomCodeEditor.GetSpecSymbolCount(SpecClass: TSpecSymbolClass): integer;
  2367. begin
  2368. { Abstract }
  2369. GetSpecSymbolCount:=0;
  2370. end;
  2371. function TCustomCodeEditor.GetSpecSymbol(SpecClass: TSpecSymbolClass; Index: integer): string;
  2372. begin
  2373. Abstract;
  2374. GetSpecSymbol:='';
  2375. end;
  2376. function TCustomCodeEditor.IsReservedWord(const S: string): boolean;
  2377. begin
  2378. { Abstract }
  2379. IsReservedWord:=false;
  2380. end;
  2381. function TCustomCodeEditor.TranslateCodeTemplate(const Shortcut: string; ALines: PUnsortedStringCollection): boolean;
  2382. begin
  2383. { Abstract }
  2384. TranslateCodeTemplate:=false;
  2385. end;
  2386. function TCustomCodeEditor.CompleteCodeWord(const WordS: string; var Text: string): boolean;
  2387. begin
  2388. { Abstract }
  2389. Text:='';
  2390. CompleteCodeWord:=false;
  2391. end;
  2392. function TCustomCodeEditor.GetCodeCompleteWord: string;
  2393. begin
  2394. { Abstract }
  2395. GetCodeCompleteWord:='';
  2396. end;
  2397. procedure TCustomCodeEditor.AdjustSelection(DeltaX, DeltaY: sw_integer);
  2398. begin
  2399. AdjustSelectionPos(CurPos.X,CurPos.Y,DeltaX,DeltaY);
  2400. end;
  2401. procedure TCustomCodeEditor.TrackCursor(Center: boolean);
  2402. var D: TPoint;
  2403. begin
  2404. D:=Delta;
  2405. if CurPos.Y<Delta.Y then D.Y:=CurPos.Y else
  2406. if CurPos.Y>Delta.Y+Size.Y-1 then D.Y:=CurPos.Y-Size.Y+1;
  2407. if CurPos.X<Delta.X then D.X:=CurPos.X else
  2408. if CurPos.X>Delta.X+Size.X-1 then D.X:=CurPos.X-Size.X+1;
  2409. if {((Delta.X<>D.X) or (Delta.Y<>D.Y)) and }Center then
  2410. begin
  2411. { loose centering for debugger PM }
  2412. while (CurPos.Y-D.Y)<(Size.Y div 3) do Dec(D.Y);
  2413. while (CurPos.Y-D.Y)>2*(Size.Y div 3) do Inc(D.Y);
  2414. end;
  2415. if (Delta.X<>D.X) or (Delta.Y<>D.Y) then
  2416. ScrollTo(D.X,D.Y);
  2417. DrawCursor;
  2418. end;
  2419. procedure TCustomCodeEditor.ScrollTo(X, Y: sw_Integer);
  2420. begin
  2421. inherited ScrollTo(X,Y);
  2422. if (HScrollBar=nil) or (VScrollBar=nil) then
  2423. begin Delta.X:=X; Delta.Y:=Y; end;
  2424. DrawView;
  2425. end;
  2426. function TCustomCodeEditor.IsModal: boolean;
  2427. var IsM: boolean;
  2428. begin
  2429. IsM:=GetState(sfModal);
  2430. if Assigned(Owner) then
  2431. IsM:=IsM or Owner^.GetState(sfModal);
  2432. IsModal:=IsM;
  2433. end;
  2434. procedure TCustomCodeEditor.FlagsChanged(OldFlags: longint);
  2435. var I: sw_integer;
  2436. begin
  2437. Lock;
  2438. if ((OldFlags xor GetFlags) and efCodeComplete)<>0 then
  2439. ClearCodeCompleteWord;
  2440. SetInsertMode(IsFlagSet(efInsertMode));
  2441. if IsFlagSet(efSyntaxHighlight) then
  2442. UpdateAttrs(0,attrAll) else
  2443. for I:=0 to GetLineCount-1 do
  2444. SetLineFormat(I,'');
  2445. DrawView;
  2446. UnLock;
  2447. end;
  2448. procedure TCustomCodeEditor.LimitsChanged;
  2449. begin
  2450. Abstract;
  2451. end;
  2452. procedure TCustomCodeEditor.DoLimitsChanged;
  2453. begin
  2454. SetLimit(MaxLineLength+1,GetLineCount);
  2455. end;
  2456. procedure TCustomCodeEditor.BindingsChanged;
  2457. begin
  2458. { Abstract }
  2459. end;
  2460. procedure TCustomCodeEditor.ContentsChanged;
  2461. begin
  2462. DrawView;
  2463. end;
  2464. procedure TCustomCodeEditor.ConvertEvent(var Event: TEvent);
  2465. var
  2466. Key: Word;
  2467. begin
  2468. if Event.What = evKeyDown then
  2469. begin
  2470. if (Event.KeyShift and kbShift <> 0) and
  2471. (Event.ScanCode >= $47) and (Event.ScanCode <= $51) then
  2472. Event.CharCode := #0;
  2473. Key := Event.KeyCode;
  2474. if KeyState <> 0 then
  2475. begin
  2476. if (Lo(Key) >= $01) and (Lo(Key) <= $1A) then Inc(Key, $40);
  2477. if (Lo(Key) >= $61) and (Lo(Key) <= $7A) then Dec(Key, $20);
  2478. end;
  2479. Key := ScanKeyMap(KeyMap[KeyState], Key);
  2480. if (KeyState<>0) and (Key=0) then
  2481. ClearEvent(Event); { eat second key if unrecognized after ^Q or ^K }
  2482. KeyState := 0;
  2483. if Key <> 0 then
  2484. if Hi(Key) = $FF then
  2485. begin
  2486. KeyState := Lo(Key);
  2487. ClearEvent(Event);
  2488. end
  2489. else
  2490. begin
  2491. Event.What := evCommand;
  2492. Event.Command := Key;
  2493. end;
  2494. end;
  2495. end;
  2496. procedure TCustomCodeEditor.SetLineFlagState(LineNo: sw_integer; Flags: longint; ASet: boolean);
  2497. var L: PCustomLine;
  2498. begin
  2499. L:=GetLine(LineNo);
  2500. if Assigned(L) then
  2501. with L^ do
  2502. if ASet then
  2503. SetFlags(GetFlags or Flags)
  2504. else
  2505. SetFlags(GetFlags and not Flags);
  2506. end;
  2507. procedure TCustomCodeEditor.SetLineFlagExclusive(Flags: longint; LineNo: sw_integer);
  2508. var I,Count: sw_integer;
  2509. L: PCustomLine;
  2510. begin
  2511. Count:=GetLineCount;
  2512. for I:=0 to Count-1 do
  2513. begin
  2514. L:=GetLine(I);
  2515. if I=LineNo then
  2516. L^.SetFlags(L^.GetFlags or Flags)
  2517. else
  2518. L^.SetFlags(L^.GetFlags and (not Flags));
  2519. end;
  2520. end;
  2521. procedure TCustomCodeEditor.HandleEvent(var Event: TEvent);
  2522. var DontClear : boolean;
  2523. procedure CheckScrollBar(P: PScrollBar; var D: Sw_Integer);
  2524. begin
  2525. if (Event.InfoPtr = P) and (P^.Value <> D) then
  2526. begin
  2527. D := P^.Value;
  2528. DrawView;
  2529. end;
  2530. end;
  2531. procedure GetMousePos(var P: TPoint);
  2532. begin
  2533. MakeLocal(Event.Where,P);
  2534. Inc(P.X,Delta.X); Inc(P.Y,Delta.Y);
  2535. end;
  2536. type TCCAction = (ccCheck,ccClear,ccDontCare);
  2537. var
  2538. StartP,P: TPoint;
  2539. E: TEvent;
  2540. OldEvent : PEvent;
  2541. CCAction: TCCAction;
  2542. begin
  2543. CCAction:=ccClear;
  2544. E:=Event;
  2545. OldEvent:=CurEvent;
  2546. if (E.What and (evMouse or evKeyboard))<>0 then
  2547. CurEvent:=@E;
  2548. if (InASCIIMode=false) or (Event.What<>evKeyDown) then
  2549. if (Event.What<>evKeyDown) or
  2550. ((Event.KeyCode<>kbEnter) and (Event.KeyCode<>kbEsc)) or
  2551. (GetCompleteState<>csOffering) then
  2552. ConvertEvent(Event);
  2553. case Event.What of
  2554. evMouseDown :
  2555. if MouseInView(Event.Where) then
  2556. if (Event.Buttons=mbRightButton) then
  2557. begin
  2558. MakeLocal(Event.Where,P); Inc(P.X); Inc(P.Y);
  2559. LocalMenu(P);
  2560. ClearEvent(Event);
  2561. end else
  2562. if Event.Buttons=mbLeftButton then
  2563. begin
  2564. GetMousePos(P);
  2565. StartP:=P;
  2566. SetCurPtr(P.X,P.Y);
  2567. repeat
  2568. GetMousePos(P);
  2569. if PointOfs(P)<PointOfs(StartP)
  2570. then SetSelection(P,StartP)
  2571. else SetSelection(StartP,P);
  2572. SetCurPtr(P.X,P.Y);
  2573. DrawView;
  2574. until not MouseEvent(Event, evMouseMove+evMouseAuto);
  2575. DrawView;
  2576. end;
  2577. evKeyDown :
  2578. begin
  2579. { Scancode is almost never zero PM }
  2580. { this is supposed to enable entering of ASCII chars below 32,
  2581. which are normally interpreted as control chars. So, when you enter
  2582. Alt+24 (on the numeric pad) then this will normally move the cursor
  2583. one line down, but if you do it in ASCII mode (also after Ctrl+B)
  2584. then this will insert the ASCII #24 char (upper arrow) in the
  2585. source code. - Gabor }
  2586. if InASCIIMode {and (Event.CharCode<>0)} then
  2587. begin
  2588. AddChar(Event.CharCode);
  2589. if (GetCompleteState<>csDenied) or (Event.CharCode=#32) then
  2590. CCAction:=ccCheck
  2591. else
  2592. CCAction:=ccClear;
  2593. end
  2594. else
  2595. begin
  2596. DontClear:=false;
  2597. case Event.KeyCode of
  2598. kbAltF10 :
  2599. Message(@Self,evCommand,cmLocalMenu,@Self);
  2600. kbEnter :
  2601. if GetCompleteState=csOffering then
  2602. CodeCompleteApply
  2603. else
  2604. Message(@Self,evCommand,cmNewLine,nil);
  2605. kbEsc :
  2606. if GetCompleteState=csOffering then
  2607. CodeCompleteCancel else
  2608. if IsModal then
  2609. DontClear:=true;
  2610. else
  2611. case Event.CharCode of
  2612. #9,#32..#255 :
  2613. if (Event.CharCode=#9) and IsModal then
  2614. DontClear:=true
  2615. else
  2616. begin
  2617. NoSelect:=true;
  2618. AddChar(Event.CharCode);
  2619. NoSelect:=false;
  2620. if (GetCompleteState<>csDenied) or (Event.CharCode=#32) then
  2621. CCAction:=ccCheck
  2622. else
  2623. CCAction:=ccClear;
  2624. end;
  2625. else
  2626. DontClear:=true;
  2627. end; { case Event.CharCode .. }
  2628. end; { case Event.KeyCode .. }
  2629. if not DontClear then
  2630. ClearEvent(Event);
  2631. end;
  2632. InASCIIMode:=false;
  2633. end;
  2634. evCommand :
  2635. begin
  2636. DontClear:=false;
  2637. case Event.Command of
  2638. cmASCIIChar : InASCIIMode:=not InASCIIMode;
  2639. cmAddChar : AddChar(chr(longint(Event.InfoPtr)));
  2640. cmCharLeft : CharLeft;
  2641. cmCharRight : CharRight;
  2642. cmWordLeft : WordLeft;
  2643. cmWordRight : WordRight;
  2644. cmLineStart : LineStart;
  2645. cmLineEnd : LineEnd;
  2646. cmLineUp : LineUp;
  2647. cmLineDown : LineDown;
  2648. cmPageUp : PageUp;
  2649. cmPageDown : PageDown;
  2650. cmTextStart : TextStart;
  2651. cmTextEnd : TextEnd;
  2652. cmNewLine : InsertNewLine;
  2653. cmBreakLine : BreakLine;
  2654. cmBackSpace : BackSpace;
  2655. cmDelChar : DelChar;
  2656. cmDelWord : DelWord;
  2657. cmDelStart : DelStart;
  2658. cmDelEnd : DelEnd;
  2659. cmDelLine : DelLine;
  2660. cmInsMode : InsMode;
  2661. cmStartSelect : StartSelect;
  2662. cmHideSelect : HideSelect;
  2663. cmUpdateTitle : ;
  2664. cmEndSelect : EndSelect;
  2665. cmDelSelect : DelSelect;
  2666. cmCopyBlock : CopyBlock;
  2667. cmMoveBlock : MoveBlock;
  2668. cmIndentBlock : IndentBlock;
  2669. cmUnindentBlock : UnindentBlock;
  2670. cmSelStart : JumpSelStart;
  2671. cmSelEnd : JumpSelEnd;
  2672. cmLastCursorPos : JumpToLastCursorPos;
  2673. cmJumpMark0..cmJumpMark9 : JumpMark(Event.Command-cmJumpMark0);
  2674. cmSetMark0..cmSetMark9 : DefineMark(Event.Command-cmSetMark0);
  2675. cmSelectWord : SelectWord;
  2676. cmSelectLine : SelectLine;
  2677. cmWriteBlock : WriteBlock;
  2678. cmReadBlock : ReadBlock;
  2679. cmPrintBlock : PrintBlock;
  2680. { ------ }
  2681. cmFind : Find;
  2682. cmReplace : Replace;
  2683. cmSearchAgain : DoSearchReplace;
  2684. cmJumpLine : GotoLine;
  2685. { ------ }
  2686. cmCut : ClipCut;
  2687. cmCopy : ClipCopy;
  2688. cmPaste : ClipPaste;
  2689. {$ifdef WinClipSupported}
  2690. cmCopyWin : ClipCopyWin;
  2691. cmPasteWin : ClipPasteWin;
  2692. {$endif WinClipSupported}
  2693. cmUndo : Undo;
  2694. cmRedo : Redo;
  2695. cmClear : DelSelect;
  2696. cmExpandCodeTemplate: ExpandCodeTemplate;
  2697. cmLocalMenu :
  2698. begin
  2699. P:=CurPos; Inc(P.X); Inc(P.Y);
  2700. LocalMenu(P);
  2701. end;
  2702. else
  2703. begin
  2704. DontClear:=true;
  2705. CCAction:=ccDontCare;
  2706. end;
  2707. end;
  2708. if DontClear=false then
  2709. ClearEvent(Event);
  2710. end;
  2711. {$ifdef TEST_PARTIAL_SYNTAX}
  2712. evIdle :
  2713. begin
  2714. { Complete syntax by 20 lines increment }
  2715. { could already be quite lengthy on slow systems }
  2716. if not GetSyntaxCompleted then
  2717. UpdateAttrsRange(GetLastSyntaxedLine,GetLastSyntaxedLine+20,AttrAll);
  2718. end;
  2719. {$endif TEST_PARTIAL_SYNTAX}
  2720. evBroadcast :
  2721. begin
  2722. CCAction:=ccDontCare;
  2723. case Event.Command of
  2724. cmUpdate :
  2725. Update;
  2726. cmClearLineHighlights :
  2727. SetLineFlagExclusive(lfHighlightRow,-1);
  2728. cmResetDebuggerRow :
  2729. SetLineFlagExclusive(lfDebuggerRow,-1);
  2730. cmScrollBarChanged:
  2731. if (Event.InfoPtr = HScrollBar) or
  2732. (Event.InfoPtr = VScrollBar) then
  2733. begin
  2734. CheckScrollBar(HScrollBar, Delta.X);
  2735. CheckScrollBar(VScrollBar, Delta.Y);
  2736. end;
  2737. end;
  2738. end;
  2739. else CCAction:=ccDontCare;
  2740. end;
  2741. inherited HandleEvent(Event);
  2742. CurEvent:=OldEvent;
  2743. case CCAction of
  2744. ccCheck : CodeCompleteCheck;
  2745. ccClear : ClearCodeCompleteWord;
  2746. end;
  2747. end;
  2748. procedure TCustomCodeEditor.UpdateUndoRedo(cm : word; action : byte);
  2749. var UndoMenu : PMenuItem;
  2750. begin
  2751. UndoMenu:=PAdvancedMenuBar(MenuBar)^.GetMenuItem(cm);
  2752. if assigned(UndoMenu) then
  2753. begin
  2754. If assigned(UndoMenu^.Param) then
  2755. DisposeStr(UndoMenu^.Param);
  2756. if action<lastaction then
  2757. UndoMenu^.Param:=NewStr(ActionString[action]);
  2758. end;
  2759. end;
  2760. procedure TCustomCodeEditor.Update;
  2761. begin
  2762. Lock;
  2763. LimitsChanged;
  2764. SelectionChanged; HighlightChanged;
  2765. UnLock;
  2766. end;
  2767. function TCustomCodeEditor.GetLocalMenu: PMenu;
  2768. begin
  2769. GetLocalMenu:=nil;
  2770. end;
  2771. function TCustomCodeEditor.GetCommandTarget: PView;
  2772. begin
  2773. GetCommandTarget:=@Self;
  2774. end;
  2775. function TCustomCodeEditor.CreateLocalMenuView(var Bounds: TRect; M: PMenu): PMenuPopup;
  2776. var MV: PMenuPopup;
  2777. begin
  2778. New(MV, Init(Bounds, M));
  2779. CreateLocalMenuView:=MV;
  2780. end;
  2781. procedure TCustomCodeEditor.LocalMenu(P: TPoint);
  2782. var M: PMenu;
  2783. MV: PMenuPopUp;
  2784. R: TRect;
  2785. Re: word;
  2786. begin
  2787. M:=GetLocalMenu;
  2788. if M=nil then Exit;
  2789. if LastLocalCmd<>0 then
  2790. M^.Default:=SearchMenuItem(M,LastLocalCmd);
  2791. Desktop^.GetExtent(R);
  2792. MakeGlobal(P,R.A); {Desktop^.MakeLocal(R.A,R.A);}
  2793. MV:=CreateLocalMenuView(R,M);
  2794. Re:=Application^.ExecView(MV);
  2795. if M^.Default=nil then LastLocalCmd:=0
  2796. else LastLocalCmd:=M^.Default^.Command;
  2797. Dispose(MV, Done);
  2798. if Re<>0 then
  2799. Message(GetCommandTarget,evCommand,Re,@Self);
  2800. end;
  2801. procedure TCustomCodeEditor.Draw;
  2802. var SelectColor,
  2803. HighlightColColor,
  2804. HighlightRowColor,
  2805. ErrorMessageColor : word;
  2806. B: TDrawBuffer;
  2807. X,Y,AX,AY,MaxX: sw_integer;
  2808. PX: TPoint;
  2809. LineCount: sw_integer;
  2810. Line: PCustomLine;
  2811. LineText,Format: string;
  2812. isBreak : boolean;
  2813. C: char;
  2814. FreeFormat: array[0..255] of boolean;
  2815. Color: word;
  2816. ColorTab: array[coFirstColor..coLastColor] of word;
  2817. ErrorLine: integer;
  2818. ErrorMsg: string[MaxViewWidth];
  2819. function CombineColors(Orig,Modifier: byte): byte;
  2820. var Color: byte;
  2821. begin
  2822. if (Modifier and $0f)=0 then
  2823. Color:=(Orig and $0f) or (Modifier and $f0)
  2824. else
  2825. Color:=(Orig and $f0) or (Modifier and $0f);
  2826. { do not allow invisible }
  2827. { use white as foreground in this case }
  2828. if (Color and $f) = ((Color div $10) and $7) then
  2829. Color:=(Color and $F0) or $F;
  2830. CombineColors:=Color;
  2831. end;
  2832. begin
  2833. if LockFlag>0 then
  2834. begin
  2835. DrawCalled:=true;
  2836. Exit;
  2837. end;
  2838. DrawCalled:=false;
  2839. ErrorMsg:=copy(GetErrorMessage,1,MaxViewWidth);
  2840. if ErrorMsg='' then ErrorLine:=-1 else
  2841. if (CurPos.Y-Delta.Y)<(Size.Y div 2) then ErrorLine:=Size.Y-1
  2842. else ErrorLine:=0;
  2843. LineCount:=GetLineCount;
  2844. ColorTab[coTextColor]:=GetColor(1);
  2845. ColorTab[coWhiteSpaceColor]:=GetColor(2);
  2846. ColorTab[coCommentColor]:=GetColor(3);
  2847. ColorTab[coReservedWordColor]:=GetColor(4);
  2848. ColorTab[coIdentifierColor]:=GetColor(5);
  2849. ColorTab[coStringColor]:=GetColor(6);
  2850. ColorTab[coNumberColor]:=GetColor(7);
  2851. ColorTab[coAssemblerColor]:=GetColor(8);
  2852. ColorTab[coSymbolColor]:=GetColor(9);
  2853. ColorTab[coDirectiveColor]:=GetColor(13);
  2854. ColorTab[coHexNumberColor]:=GetColor(14);
  2855. ColorTab[coTabColor]:=GetColor(15);
  2856. { break same as error }
  2857. ColorTab[coBreakColor]:=GetColor(16);
  2858. SelectColor:=GetColor(10);
  2859. HighlightColColor:=GetColor(11);
  2860. HighlightRowColor:=GetColor(12);
  2861. ErrorMessageColor:=GetColor(16);
  2862. {$ifdef TEST_PARTIAL_SYNTAX}
  2863. If GetLastSyntaxedLine<Delta.Y+Size.Y then
  2864. UpdateAttrsRange(GetLastSyntaxedLine,Delta.Y+Size.Y,AttrAll);
  2865. {$endif TEST_PARTIAL_SYNTAX}
  2866. for Y:=0 to Size.Y-1 do
  2867. if Y=ErrorLine then
  2868. begin
  2869. MoveChar(B,' ',ErrorMessageColor,Size.X);
  2870. MoveStr(B,ErrorMsg,ErrorMessageColor);
  2871. WriteLine(0,Y,Size.X,1,B);
  2872. end else
  2873. begin
  2874. AY:=Delta.Y+Y;
  2875. Color:=ColorTab[coTextColor];
  2876. FillChar(FreeFormat,SizeOf(FreeFormat),1);
  2877. MoveChar(B,' ',Color,Size.X);
  2878. if AY<LineCount then
  2879. begin
  2880. Line:=GetLine(AY);
  2881. IsBreak:=GetLine(AY)^.IsFlagSet(lfBreakpoint);
  2882. end
  2883. else
  2884. begin
  2885. Line:=nil;
  2886. IsBreak:=false;
  2887. end;
  2888. GetDisplayTextFormat(AY,LineText,Format);
  2889. { if FlagSet(efSyntaxHighlight) then MaxX:=length(LineText)+1
  2890. else }MaxX:=Size.X+Delta.X;
  2891. for X:=1 to Min(MaxX,255) do
  2892. begin
  2893. AX:=Delta.X+X-1;
  2894. if X<=length(LineText) then C:=LineText[X] else C:=' ';
  2895. PX.X:=AX-Delta.X; PX.Y:=AY;
  2896. if (Highlight.A.X<>Highlight.B.X) or (Highlight.A.Y<>Highlight.B.Y) then
  2897. begin
  2898. if (PointOfs(Highlight.A)<=PointOfs(PX)) and (PointOfs(PX)<PointOfs(Highlight.B)) then
  2899. begin
  2900. Color:=SelectColor;
  2901. FreeFormat[X]:=false;
  2902. end;
  2903. end else
  2904. { no highlight }
  2905. begin
  2906. if IsFlagSet(efVerticalBlocks) then
  2907. begin
  2908. if (SelStart.X<=AX) and (AX<=SelEnd.X) and
  2909. (SelStart.Y<=AY) and (AY<=SelEnd.Y) then
  2910. begin Color:=SelectColor; FreeFormat[X]:=false; end;
  2911. end else
  2912. if PointOfs(SelStart)<>PointOfs(SelEnd) then
  2913. if (PointOfs(SelStart)<=PointOfs(PX)) and (PointOfs(PX)<PointOfs(SelEnd)) then
  2914. begin Color:=SelectColor; FreeFormat[X]:=false; end;
  2915. end;
  2916. if FreeFormat[X] then
  2917. if X<=length(Format) then
  2918. {Color:=ColorTab[ord(Format[X])] else Color:=ColorTab[coTextColor];
  2919. this give BoundsCheckError with -Cr quite often PM }
  2920. Color:=ColorTab[ord(Format[X]) mod (coLastColor + 1)] else Color:=ColorTab[coTextColor];
  2921. if IsFlagSet(efHighlightRow) and
  2922. (PX.Y=CurPos.Y) then
  2923. begin
  2924. Color:=CombineColors(Color,HighlightRowColor);
  2925. FreeFormat[X]:=false;
  2926. end;
  2927. if IsFlagSet(efHighlightColumn) and (PX.X=CurPos.X) then
  2928. begin
  2929. Color:=CombineColors(Color,HighlightColColor);
  2930. FreeFormat[X]:=false;
  2931. end;
  2932. if Assigned(Line) and Line^.IsFlagSet(lfHighlightRow) then
  2933. begin
  2934. Color:=CombineColors(Color,HighlightRowColor);
  2935. FreeFormat[X]:=false;
  2936. end;
  2937. if isbreak then
  2938. begin
  2939. Color:=ColorTab[coBreakColor];
  2940. FreeFormat[X]:=false;
  2941. end;
  2942. if Assigned(Line) and Line^.isFlagSet(lfDebuggerRow) then
  2943. begin
  2944. Color:=CombineColors(Color,HighlightRowColor);
  2945. FreeFormat[X]:=false;
  2946. end;
  2947. if (0<=X-1-Delta.X) and (X-1-Delta.X<MaxViewWidth) then
  2948. MoveChar(B[X-1-Delta.X],C,Color,1);
  2949. end;
  2950. WriteLine(0,Y,Size.X,1,B);
  2951. end;
  2952. DrawCursor;
  2953. end;
  2954. procedure TCustomCodeEditor.DrawCursor;
  2955. begin
  2956. if lockflag>0 then
  2957. DrawCursorCalled:=true
  2958. else
  2959. SetCursor(CurPos.X-Delta.X,CurPos.Y-Delta.Y);
  2960. SetState(sfCursorIns,Overwrite);
  2961. end;
  2962. function TCustomCodeEditor.Overwrite: boolean;
  2963. begin
  2964. Overwrite:=not IsFlagSet(efInsertMode);
  2965. end;
  2966. procedure TCustomCodeEditor.SetCodeCompleteWord(const S: string);
  2967. begin
  2968. if S<>'' then
  2969. SetCompleteState(csOffering)
  2970. else
  2971. SetCompleteState(csInactive);
  2972. end;
  2973. procedure TCustomCodeEditor.ClearCodeCompleteWord;
  2974. begin
  2975. SetCodeCompleteWord('');
  2976. SetCompleteState(csInactive);
  2977. end;
  2978. function TCustomCodeEditor.GetCompleteState: TCompleteState;
  2979. begin
  2980. { Abstract }
  2981. GetCompleteState:=csInactive;
  2982. end;
  2983. procedure TCustomCodeEditor.SetCompleteState(AState: TCompleteState);
  2984. begin
  2985. { Abstract }
  2986. end;
  2987. function TCustomCodeEditor.UpdateAttrs(FromLine: sw_integer; Attrs: byte): sw_integer;
  2988. begin
  2989. Abstract;
  2990. UpdateAttrs:=-1;
  2991. end;
  2992. function TCustomCodeEditor.UpdateAttrsRange(FromLine, ToLine: sw_integer; Attrs: byte): sw_integer;
  2993. begin
  2994. Abstract;
  2995. UpdateAttrsRange:=-1;
  2996. end;
  2997. procedure TCustomCodeEditor.AddAction(AAction: byte; AStartPos, AEndPos: TPoint; AText: string);
  2998. begin
  2999. { Abstract }
  3000. end;
  3001. procedure TCustomCodeEditor.AddGroupedAction(AAction : byte);
  3002. begin
  3003. { Abstract }
  3004. end;
  3005. procedure TCustomCodeEditor.CloseGroupedAction(AAction : byte);
  3006. begin
  3007. { Abstract }
  3008. end;
  3009. function TCustomCodeEditor.GetUndoActionCount: sw_integer;
  3010. begin
  3011. { Abstract }
  3012. GetUndoActionCount:=0;
  3013. end;
  3014. function TCustomCodeEditor.GetRedoActionCount: sw_integer;
  3015. begin
  3016. { Abstract }
  3017. GetRedoActionCount:=0;
  3018. end;
  3019. procedure TCustomCodeEditor.Indent;
  3020. var S, PreS: string;
  3021. Shift: integer;
  3022. begin
  3023. S:=GetLineText(CurPos.Y);
  3024. if CurPos.Y>0 then
  3025. PreS:=RTrim(GetLineText(CurPos.Y-1),not IsFlagSet(efUseTabCharacters))
  3026. else
  3027. PreS:='';
  3028. if CurPos.X>=length(PreS) then
  3029. Shift:=GetTabSize
  3030. else
  3031. begin
  3032. Shift:=1;
  3033. while (CurPos.X+Shift<length(PreS)) and (PreS[CurPos.X+Shift]<>' ') do
  3034. Inc(Shift);
  3035. end;
  3036. SetLineText(CurPos.Y,RExpand(copy(S,1,CurPos.X+1),CurPos.X+1)+CharStr(' ',Shift)+copy(S,CurPos.X+2,255));
  3037. SetCurPtr(CurPos.X+Shift,CurPos.Y);
  3038. UpdateAttrs(CurPos.Y,attrAll);
  3039. DrawLines(CurPos.Y);
  3040. SetModified(true);
  3041. end;
  3042. procedure TCustomCodeEditor.CharLeft;
  3043. begin
  3044. if CurPos.X=0 then Exit;
  3045. SetCurPtr(CurPos.X-1,CurPos.Y);
  3046. end;
  3047. procedure TCustomCodeEditor.CharRight;
  3048. begin
  3049. if CurPos.X>=MaxLineLength then
  3050. Exit;
  3051. SetCurPtr(CurPos.X+1,CurPos.Y);
  3052. end;
  3053. procedure TCustomCodeEditor.WordLeft;
  3054. var X, Y: sw_integer;
  3055. Line: string;
  3056. GotIt,FoundNonSeparator: boolean;
  3057. begin
  3058. X:=CurPos.X;
  3059. Y:=CurPos.Y;
  3060. GotIt:=false;
  3061. FoundNonSeparator:=false;
  3062. while (Y>=0) do
  3063. begin
  3064. if Y=CurPos.Y then
  3065. begin
  3066. X:=length(GetDisplayText(Y));
  3067. if CurPos.X<X then
  3068. X:=CurPos.X; Dec(X);
  3069. if (X=-1) then
  3070. begin
  3071. Dec(Y);
  3072. if Y>=0 then
  3073. X:=length(GetDisplayText(Y));
  3074. Break;
  3075. end;
  3076. end
  3077. else
  3078. X:=length(GetDisplayText(Y))-1;
  3079. Line:=GetDisplayText(Y);
  3080. while (X>=0) and (GotIt=false) do
  3081. begin
  3082. if FoundNonSeparator then
  3083. begin
  3084. if IsWordSeparator(Line[X+1]) then
  3085. begin
  3086. Inc(X);
  3087. GotIt:=true;
  3088. Break;
  3089. end;
  3090. end
  3091. else
  3092. if not IsWordSeparator(Line[X+1]) then
  3093. FoundNonSeparator:=true;
  3094. Dec(X);
  3095. if (X=0) and (IsWordSeparator(Line[1])=false) then
  3096. begin
  3097. GotIt:=true;
  3098. Break;
  3099. end;
  3100. end;
  3101. if GotIt then
  3102. Break;
  3103. X:=0;
  3104. Dec(Y);
  3105. if Y>=0 then
  3106. begin
  3107. X:=length(GetDisplayText(Y));
  3108. Break;
  3109. end;
  3110. end;
  3111. if Y<0 then Y:=0; if X<0 then X:=0;
  3112. SetCurPtr(X,Y);
  3113. end;
  3114. procedure TCustomCodeEditor.WordRight;
  3115. var X, Y: sw_integer;
  3116. Line: string;
  3117. GotIt: boolean;
  3118. begin
  3119. X:=CurPos.X; Y:=CurPos.Y; GotIt:=false;
  3120. while (Y<GetLineCount) do
  3121. begin
  3122. if Y=CurPos.Y then
  3123. begin
  3124. X:=CurPos.X; Inc(X);
  3125. if (X>length(GetDisplayText(Y))-1) then
  3126. begin Inc(Y); X:=0; end;
  3127. end else X:=0;
  3128. Line:=GetDisplayText(Y);
  3129. while (X<=length(Line)+1) and (GotIt=false) and (Line<>'') do
  3130. begin
  3131. if X=length(Line)+1 then begin GotIt:=true; Dec(X); Break end;
  3132. if IsWordSeparator(Line[X]) then
  3133. begin
  3134. while (Y<GetLineCount) and
  3135. (X<=length(Line)) and (IsWordSeparator(Line[X])) do
  3136. begin
  3137. Inc(X);
  3138. if X>=length(Line) then
  3139. begin GotIt:=true; Dec(X); Break; end;
  3140. end;
  3141. if (GotIt=false) and (X<length(Line)) then
  3142. begin
  3143. Dec(X);
  3144. GotIt:=true;
  3145. Break;
  3146. end;
  3147. end;
  3148. Inc(X);
  3149. end;
  3150. if GotIt then Break;
  3151. X:=0;
  3152. Inc(Y);
  3153. if (Y<GetLineCount) then
  3154. begin
  3155. Line:=GetDisplayText(Y);
  3156. if (Line<>'') and (IsWordSeparator(Line[1])=false) then Break;
  3157. end;
  3158. end;
  3159. if Y=GetLineCount then Y:=GetLineCount-1;
  3160. SetCurPtr(X,Y);
  3161. end;
  3162. procedure TCustomCodeEditor.LineStart;
  3163. begin
  3164. SetCurPtr(0,CurPos.Y);
  3165. end;
  3166. procedure TCustomCodeEditor.LineEnd;
  3167. var
  3168. s : string;
  3169. i : longint;
  3170. begin
  3171. if CurPos.Y<GetLineCount then
  3172. begin
  3173. s:=GetDisplayText(CurPos.Y);
  3174. i:=length(s);
  3175. while (i>0) and (s[i]=' ') do
  3176. dec(i);
  3177. SetCurPtr(i,CurPos.Y);
  3178. end
  3179. else
  3180. SetCurPtr(0,CurPos.Y);
  3181. end;
  3182. procedure TCustomCodeEditor.LineUp;
  3183. begin
  3184. if CurPos.Y>0 then
  3185. SetCurPtr(CurPos.X,CurPos.Y-1);
  3186. end;
  3187. procedure TCustomCodeEditor.LineDown;
  3188. begin
  3189. if (CurPos.Y<GetLineCount-1) then
  3190. SetCurPtr(CurPos.X,CurPos.Y+1);
  3191. end;
  3192. procedure TCustomCodeEditor.PageUp;
  3193. begin
  3194. ScrollTo(Delta.X,Max(Delta.Y-Size.Y,0));
  3195. SetCurPtr(CurPos.X,Max(0,CurPos.Y-(Size.Y)));
  3196. end;
  3197. procedure TCustomCodeEditor.PageDown;
  3198. begin
  3199. ScrollTo(Delta.X,Min(Delta.Y+Size.Y,GetLineCount-1));
  3200. SetCurPtr(CurPos.X,Min(GetLineCount-1,CurPos.Y+(Size.Y{-1})));
  3201. end;
  3202. procedure TCustomCodeEditor.TextStart;
  3203. begin
  3204. SetCurPtr(0,0);
  3205. end;
  3206. procedure TCustomCodeEditor.TextEnd;
  3207. var s : string;
  3208. i : longint;
  3209. begin
  3210. s:=GetDisplayText(GetLineCount-1);
  3211. i:=length(s);
  3212. while (i>0) and (s[i]=' ') do
  3213. dec(i);
  3214. SetCurPtr(i,GetLineCount-1);
  3215. end;
  3216. procedure TCustomCodeEditor.JumpSelStart;
  3217. begin
  3218. if ValidBlock then
  3219. SetCurPtr(SelStart.X,SelStart.Y);
  3220. end;
  3221. procedure TCustomCodeEditor.JumpSelEnd;
  3222. begin
  3223. if ValidBlock then
  3224. SetCurPtr(SelEnd.X,SelEnd.Y);
  3225. end;
  3226. procedure TCustomCodeEditor.JumpMark(MarkIdx: integer);
  3227. begin
  3228. if (MarkIdx<Low(Bookmarks)) or (MarkIdx>High(Bookmarks)) then
  3229. begin ErrorBox('Invalid mark index ('+IntToStr(MarkIdx)+')',nil); Exit; end;
  3230. with Bookmarks[MarkIdx] do
  3231. if Valid=false then
  3232. InformationBox('Mark '+IntToStr(MarkIdx)+' not set.',nil)
  3233. else
  3234. SetCurPtr(Pos.X,Pos.Y);
  3235. end;
  3236. procedure TCustomCodeEditor.DefineMark(MarkIdx: integer);
  3237. begin
  3238. if (MarkIdx<Low(Bookmarks)) or (MarkIdx>High(Bookmarks)) then
  3239. begin
  3240. ErrorBox('Invalid mark index ('+IntToStr(MarkIdx)+')',nil);
  3241. Exit;
  3242. end;
  3243. with Bookmarks[MarkIdx] do
  3244. begin
  3245. Pos:=CurPos;
  3246. Valid:=true;
  3247. end;
  3248. end;
  3249. procedure TCustomCodeEditor.JumpToLastCursorPos;
  3250. begin
  3251. NotImplemented;
  3252. end;
  3253. function TCustomCodeEditor.InsertNewLine: Sw_integer;
  3254. var Ind: Sw_integer;
  3255. S,IndentStr: string;
  3256. procedure CalcIndent(LineOver: Sw_integer);
  3257. begin
  3258. if (LineOver<0) or (LineOver>GetLineCount) then Ind:=0 else
  3259. begin
  3260. IndentStr:=GetLineText(LineOver);
  3261. Ind:=0;
  3262. while (Ind<length(IndentStr)) and (IndentStr[Ind+1]=' ') do
  3263. Inc(Ind);
  3264. end;
  3265. IndentStr:=CharStr(' ',Ind);
  3266. end;
  3267. var SelBack: sw_integer;
  3268. SCP: TPoint;
  3269. HoldUndo : Boolean;
  3270. begin
  3271. if IsReadOnly then begin InsertNewLine:=-1; Exit; end;
  3272. Lock;
  3273. SCP:=CurPos;
  3274. HoldUndo:=GetStoreUndo;
  3275. SetStoreUndo(false);
  3276. if CurPos.Y<GetLineCount then S:=GetLineText(CurPos.Y) else S:='';
  3277. if Overwrite=false then
  3278. begin
  3279. SelBack:=0;
  3280. if GetLineCount>0 then
  3281. begin
  3282. S:=GetDisplayText(CurPos.Y);
  3283. SelBack:=length(S)-SelEnd.X;
  3284. SetDisplayText(CurPos.Y,RTrim(S,not IsFlagSet(efUseTabCharacters)));
  3285. end;
  3286. SetDisplayText(CurPos.Y,copy(S,1,CurPos.X-1+1));
  3287. CalcIndent(CurPos.Y);
  3288. InsertLine(CurPos.Y+1,IndentStr+copy(S,CurPos.X+1,255));
  3289. LimitsChanged;
  3290. (* if PointOfs(SelStart)<>PointOfs(SelEnd) then { !!! check it - it's buggy !!! }
  3291. begin SelEnd.Y:=CurPos.Y+1; SelEnd.X:=length(GetLineText(CurPos.Y+1))-SelBack; end;*)
  3292. UpdateAttrs(CurPos.Y,attrAll);
  3293. SetCurPtr(Ind,CurPos.Y+1);
  3294. {$ifdef Undo}
  3295. SetStoreUndo(HoldUndo);
  3296. Addaction(eaInsertLine,SCP,CurPos,IndentStr);
  3297. SetStoreUndo(false);
  3298. {$endif Undo}
  3299. AdjustSelection(CurPos.X-SCP.X,CurPos.Y-SCP.Y);
  3300. end else
  3301. begin
  3302. CalcIndent(CurPos.Y);
  3303. if CurPos.Y=GetLineCount-1 then
  3304. begin
  3305. AddLine(IndentStr);
  3306. AdjustSelection(0,1);
  3307. LimitsChanged;
  3308. {$ifdef Undo}
  3309. SetStoreUndo(HoldUndo);
  3310. UpdateAttrs(CurPos.Y,attrAll);
  3311. SetCurPtr(Ind,CurPos.Y+1);
  3312. Addaction(eaInsertLine,SCP,CurPos,IndentStr);
  3313. SetStoreUndo(false);
  3314. {$endif Undo}
  3315. end
  3316. else
  3317. begin
  3318. UpdateAttrs(CurPos.Y,attrAll);
  3319. SetStoreUndo(HoldUndo);
  3320. SetCurPtr(Ind,CurPos.Y+1);
  3321. SetStoreUndo(false);
  3322. end;
  3323. end;
  3324. DrawLines(CurPos.Y);
  3325. SetStoreUndo(HoldUndo);
  3326. SetModified(true);
  3327. Unlock;
  3328. end;
  3329. procedure TCustomCodeEditor.BreakLine;
  3330. begin
  3331. NotImplemented; Exit;
  3332. end;
  3333. procedure TCustomCodeEditor.BackSpace;
  3334. var S,PreS: string;
  3335. OI,CI,CP,Y,TX: Sw_integer;
  3336. SCP,SC1 : TPoint;
  3337. HoldUndo : Boolean;
  3338. begin
  3339. if IsReadOnly then Exit;
  3340. Lock;
  3341. SCP:=CurPos;
  3342. HoldUndo:=GetStoreUndo;
  3343. SetStoreUndo(false);
  3344. if CurPos.X=0 then
  3345. begin
  3346. if CurPos.Y>0 then
  3347. begin
  3348. S:=GetLineText(CurPos.Y-1);
  3349. SetLineText(CurPos.Y-1,S+GetLineText(CurPos.Y));
  3350. SC1.X:=Length(S);SC1.Y:=CurPOS.Y-1;
  3351. SetStoreUndo(HoldUndo);
  3352. AddAction(eaDeleteLine,SCP,SC1,GetLineText(CurPos.Y));
  3353. SetStoreUndo(false);
  3354. DeleteLine(CurPos.Y);
  3355. LimitsChanged;
  3356. SetCurPtr(length(S),CurPos.Y-1);
  3357. end;
  3358. end
  3359. else
  3360. begin
  3361. S:=GetDisplayText(CurPos.Y);
  3362. CP:=CurPos.X-1;
  3363. if IsFlagSet(efBackspaceUnindents) then
  3364. if Trim(copy(S,1,CP+1))='' then
  3365. begin
  3366. Y:=CurPos.Y;
  3367. while (Y>0) do
  3368. begin
  3369. Dec(Y);
  3370. PreS:=GetDisplayText(Y);
  3371. if Trim(copy(PreS,1,CP+1))<>'' then Break;
  3372. end;
  3373. if Y<0 then PreS:='';
  3374. { while (CP>0) and
  3375. ( (CP>length(S)) or (S[CP]=' ') ) and
  3376. ( (CP>length(PreS)) or (PreS[CP]<>' ') ) do
  3377. Dec(CP);}
  3378. TX:=0;
  3379. while (TX<length(PreS)) and (PreS[TX+1]=' ') do
  3380. Inc(TX);
  3381. if TX<CP then CP:=TX;
  3382. end;
  3383. S:=GetLineText(CurPos.Y);
  3384. OI:=LinePosToCharIdx(CurPos.Y,CurPos.X);
  3385. CI:=LinePosToCharIdx(CurPos.Y,CP);
  3386. SetLineText(CurPos.Y,copy(S,1,CI-1)+copy(S,OI,255));
  3387. SetCurPtr(CP,CurPos.Y);
  3388. {$ifdef Undo}
  3389. SetStoreUndo(HoldUndo);
  3390. Addaction(eaDeleteText,SCP,CurPos,Copy(S,CI,OI-CI));
  3391. SetStoreUndo(false);
  3392. {$endif Undo}
  3393. end;
  3394. UpdateAttrs(CurPos.Y,attrAll);
  3395. AdjustSelection(CurPos.X-SCP.X,CurPos.Y-SCP.Y);
  3396. DrawLines(CurPos.Y);
  3397. SetStoreUndo(HoldUndo);
  3398. SetModified(true);
  3399. Unlock;
  3400. end;
  3401. procedure TCustomCodeEditor.DelChar;
  3402. var S: string;
  3403. SDX,SDY,CI : sw_integer;
  3404. HoldUndo : boolean;
  3405. SCP : TPoint;
  3406. begin
  3407. if IsReadOnly then Exit;
  3408. Lock;
  3409. HoldUndo:=GetStoreUndo;
  3410. SetStoreUndo(false);
  3411. S:=GetLineText(CurPos.Y);
  3412. if CurPos.X>=length(S) then
  3413. begin
  3414. if CurPos.Y<GetLineCount-1 then
  3415. begin
  3416. SetLineText(CurPos.Y,S+CharStr(' ',CurPOS.X-Length(S))+GetLineText(CurPos.Y+1));
  3417. SetStoreUndo(HoldUndo);
  3418. SCP.X:=0;SCP.Y:=CurPos.Y+1;
  3419. AddAction(eaDeleteLine,SCP,CurPos,GetLineText(CurPos.Y+1));
  3420. SetStoreUndo(false);
  3421. DeleteLine(CurPos.Y+1);
  3422. LimitsChanged;
  3423. SDX:=0; SDY:=-1;
  3424. end;
  3425. end
  3426. else
  3427. begin
  3428. { Problem if S[CurPos.X+1]=TAB !! PM }
  3429. CI:=LinePosToCharIdx(CurPos.Y,CurPos.X);
  3430. if S[CI]=TAB then
  3431. begin
  3432. S:=Copy(S,1,CI-1)+CharStr(' ',GetTabSize-1)+Copy(S,CI+1,255);
  3433. {$ifdef Undo}
  3434. SetStoreUndo(HoldUndo);
  3435. Addaction(eaDeleteText,CurPos,CurPos,' ');
  3436. SetStoreUndo(false);
  3437. {$endif Undo}
  3438. end
  3439. else
  3440. begin
  3441. {$ifdef Undo}
  3442. SetStoreUndo(HoldUndo);
  3443. Addaction(eaDeleteText,CurPos,CurPos,S[CI]);
  3444. SetStoreUndo(false);
  3445. {$endif Undo}
  3446. Delete(S,CI,1);
  3447. end;
  3448. SetLineText(CurPos.Y,S);
  3449. SDX:=-1; SDY:=0;
  3450. end;
  3451. SetCurPtr(CurPos.X,CurPos.Y);
  3452. UpdateAttrs(CurPos.Y,attrAll);
  3453. AdjustSelection(SDX,SDY);
  3454. DrawLines(CurPos.Y);
  3455. SetStoreUndo(HoldUndo);
  3456. SetModified(true);
  3457. Unlock;
  3458. end;
  3459. procedure TCustomCodeEditor.DelWord;
  3460. var
  3461. SP,EP : TPoint;
  3462. SelSize : sw_integer;
  3463. begin
  3464. if IsReadOnly then Exit;
  3465. Lock;
  3466. SP:=SelStart;
  3467. EP:=SelEnd;
  3468. SelectWord;
  3469. SelSize:=SelEnd.X-SelStart.X;
  3470. DelSelect;
  3471. SetSelection(SP,EP);
  3472. AdjustSelectionPos(CurPos.X,CurPos.Y,SelSize,0);
  3473. SetModified(true);
  3474. Unlock;
  3475. end;
  3476. procedure TCustomCodeEditor.DelStart;
  3477. var S: string;
  3478. begin
  3479. if IsReadOnly then Exit;
  3480. Lock;
  3481. S:=GetLineText(CurPos.Y);
  3482. if (S<>'') and (CurPos.X<>0) then
  3483. begin
  3484. SetLineText(CurPos.Y,copy(S,LinePosToCharIdx(CurPos.Y,CurPos.X),255));
  3485. SetCurPtr(0,CurPos.Y);
  3486. UpdateAttrs(CurPos.Y,attrAll);
  3487. DrawLines(CurPos.Y);
  3488. SetModified(true);
  3489. end;
  3490. Unlock;
  3491. end;
  3492. procedure TCustomCodeEditor.DelEnd;
  3493. var S: string;
  3494. begin
  3495. if IsReadOnly then Exit;
  3496. Lock;
  3497. S:=GetLineText(CurPos.Y);
  3498. if (S<>'') and (CurPos.X<>length(S)) then
  3499. begin
  3500. SetLineText(CurPos.Y,copy(S,1,LinePosToCharIdx(CurPos.Y,CurPos.X)-1));
  3501. SetCurPtr(CurPos.X,CurPos.Y);
  3502. UpdateAttrs(CurPos.Y,attrAll);
  3503. DrawLines(CurPos.Y);
  3504. SetModified(true);
  3505. end;
  3506. Unlock;
  3507. end;
  3508. procedure TCustomCodeEditor.DelLine;
  3509. var
  3510. HoldUndo : boolean;
  3511. SP : TPoint;
  3512. begin
  3513. if IsReadOnly then Exit;
  3514. Lock;
  3515. if GetLineCount>0 then
  3516. begin
  3517. SP:=CurPos;
  3518. DeleteLine(CurPos.Y);
  3519. HoldUndo:=GetStoreUndo;
  3520. SetStoreUndo(false);
  3521. LimitsChanged;
  3522. AdjustSelection(0,-1);
  3523. SetCurPtr(0,CurPos.Y);
  3524. UpdateAttrs(Max(0,CurPos.Y-1),attrAll);
  3525. DrawLines(CurPos.Y);
  3526. { put this back !!!!!!
  3527. If HoldUndo then
  3528. with Core^.UndoList^.At(Core^.UndoList^.count-1)^ do
  3529. begin
  3530. EndPos:=CurPos;
  3531. StartPos:=SP;
  3532. end;
  3533. }
  3534. SetStoreUndo(HoldUndo);
  3535. SetModified(true);
  3536. end;
  3537. Unlock;
  3538. end;
  3539. procedure TCustomCodeEditor.InsMode;
  3540. begin
  3541. SetInsertMode(Overwrite);
  3542. end;
  3543. function TCustomCodeEditor.GetCurrentWord : string;
  3544. const WordChars = ['A'..'Z','a'..'z','0'..'9','_'];
  3545. var P : TPoint;
  3546. S : String;
  3547. StartPos,EndPos : byte;
  3548. begin
  3549. P:=CurPos;
  3550. S:=GetLineText(P.Y);
  3551. StartPos:=P.X+1;
  3552. EndPos:=StartPos;
  3553. if not (S[StartPos] in WordChars) then
  3554. GetCurrentWord:=''
  3555. else
  3556. begin
  3557. While (StartPos>0) and (S[StartPos-1] in WordChars) do
  3558. Dec(StartPos);
  3559. While (EndPos<Length(S)) and (S[EndPos+1] in WordChars) do
  3560. Inc(EndPos);
  3561. GetCurrentWord:=Copy(S,StartPos,EndPos-StartPos+1);
  3562. end;
  3563. end;
  3564. procedure TCustomCodeEditor.StartSelect;
  3565. var P1,P2: TPoint;
  3566. begin
  3567. if ValidBlock=false then
  3568. begin
  3569. { SetSelection(SelStart,Limit);}
  3570. P1:=CurPos; P1.X:=0; P2:=CurPos; {P2.X:=length(GetLineText(P2.Y))+1;}
  3571. SetSelection(P1,P2);
  3572. end
  3573. else
  3574. SetSelection(CurPos,SelEnd);
  3575. if PointOfs(SelEnd)<PointOfs(SelStart) then
  3576. SetSelection(SelStart,SelStart);
  3577. CheckSels;
  3578. DrawView;
  3579. end;
  3580. procedure TCustomCodeEditor.EndSelect;
  3581. var P: TPoint;
  3582. LS: sw_integer;
  3583. begin
  3584. P:=CurPos;
  3585. { P.X:=Min(SelEnd.X,length(GetLineText(SelEnd.Y)));}
  3586. LS:=length(GetLineText(SelEnd.Y));
  3587. if LS<P.X then P.X:=LS;
  3588. CheckSels;
  3589. SetSelection(SelStart,P);
  3590. DrawView;
  3591. end;
  3592. procedure TCustomCodeEditor.DelSelect;
  3593. var LineDelta, LineCount, CurLine: Sw_integer;
  3594. StartX,EndX,LastX: Sw_integer;
  3595. S: string;
  3596. SPos : TPoint;
  3597. begin
  3598. if IsReadOnly or (ValidBlock=false) then Exit;
  3599. Lock;
  3600. LineCount:=(SelEnd.Y-SelStart.Y)+1;
  3601. LineDelta:=0; LastX:=CurPos.X;
  3602. CurLine:=SelStart.Y;
  3603. while (LineDelta<LineCount) do
  3604. begin
  3605. S:=GetDisplayText(CurLine);
  3606. if LineDelta=0 then StartX:=SelStart.X else StartX:=0;
  3607. if LineDelta=LineCount-1 then EndX:=SelEnd.X else EndX:=length(S);
  3608. if (LineDelta<LineCount-1) and ((StartX=0) and (EndX>=length(S))) then
  3609. begin
  3610. { delete the complete line }
  3611. DeleteLine(CurLine);
  3612. if CurLine>0 then
  3613. LastX:=length(GetDisplayText(CurLine-1))
  3614. else
  3615. LastX:=0;
  3616. end
  3617. else
  3618. begin
  3619. if GetStoreUndo then
  3620. begin
  3621. SPos.X:=StartX;
  3622. SPos.Y:=CurLine;
  3623. AddAction(eaDeleteText,SPos,SPos,Copy(S,StartX+1,EndX-StartX));
  3624. end;
  3625. SetDisplayText(CurLine,RExpand(copy(S,1,StartX),StartX)+copy(S,EndX+1,255));
  3626. LastX:=StartX;
  3627. if (StartX=0) and (0<LineDelta) and
  3628. not(((LineDelta=LineCount-1) and (StartX=0) and (StartX=EndX))) then
  3629. begin
  3630. S:=GetDisplayText(CurLine-1);
  3631. SetDisplayText(CurLine-1,S+GetLineText(CurLine));
  3632. DeleteLine(CurLine);
  3633. LastX:=length(S);
  3634. end
  3635. else
  3636. Inc(CurLine);
  3637. end;
  3638. Inc(LineDelta);
  3639. end;
  3640. HideSelect;
  3641. SetCurPtr(LastX,CurLine-1);
  3642. UpdateAttrs(CurPos.Y,attrAll);
  3643. DrawLines(CurPos.Y);
  3644. SetModified(true);
  3645. UnLock;
  3646. end;
  3647. procedure TCustomCodeEditor.HideSelect;
  3648. begin
  3649. SetSelection(CurPos,CurPos);
  3650. DrawLines(Delta.Y);
  3651. end;
  3652. procedure TCustomCodeEditor.CopyBlock;
  3653. var Temp: PCodeEditor;
  3654. R: TRect;
  3655. begin
  3656. if IsReadOnly or (ValidBlock=false) then Exit;
  3657. Lock;
  3658. GetExtent(R);
  3659. New(Temp, Init(R, nil, nil, nil,nil));
  3660. Temp^.InsertFrom(@Self);
  3661. (* Temp^.SelectAll(true);
  3662. { this selects one line too much because
  3663. we have a empty line at creation to avoid
  3664. negative line problems so we need to decrease SelEnd.Y }
  3665. Dec(Temp^.SelEnd.Y);*)
  3666. InsertFrom(Temp);
  3667. Dispose(Temp, Done);
  3668. UnLock;
  3669. end;
  3670. procedure TCustomCodeEditor.MoveBlock;
  3671. var Temp: PCodeEditor;
  3672. R: TRect;
  3673. OldPos: TPoint;
  3674. begin
  3675. if IsReadOnly then Exit;
  3676. if (SelStart.X=SelEnd.X) and (SelStart.Y=SelEnd.Y) then Exit;
  3677. Lock;
  3678. GetExtent(R);
  3679. New(Temp, Init(R, nil, nil, nil,nil));
  3680. Temp^.InsertFrom(@Self);
  3681. OldPos:=CurPos;
  3682. if CurPos.Y>SelStart.Y then
  3683. Dec(OldPos.Y,Temp^.GetLineCount-1);
  3684. DelSelect;
  3685. SetCurPtr(OldPos.X,OldPos.Y);
  3686. InsertFrom(Temp);
  3687. Dispose(Temp, Done);
  3688. UnLock;
  3689. end;
  3690. procedure TCustomCodeEditor.IndentBlock;
  3691. var
  3692. ey,i : Sw_integer;
  3693. S : String;
  3694. begin
  3695. if IsReadOnly then Exit;
  3696. if (SelStart.X=SelEnd.X) and (SelStart.Y=SelEnd.Y) then Exit;
  3697. Lock;
  3698. ey:=selend.y;
  3699. if selend.x=0 then
  3700. dec(ey);
  3701. for i:=selstart.y to ey do
  3702. begin
  3703. S:=GetLineText(i);
  3704. SetLineText(i,' '+S);
  3705. end;
  3706. SetCurPtr(CurPos.X,CurPos.Y);
  3707. UpdateAttrsRange(SelStart.Y,SelEnd.Y,attrAll);
  3708. DrawLines(CurPos.Y);
  3709. SetModified(true);
  3710. UnLock;
  3711. end;
  3712. procedure TCustomCodeEditor.UnindentBlock;
  3713. var
  3714. ey,i : Sw_integer;
  3715. S : String;
  3716. begin
  3717. if IsReadOnly then Exit;
  3718. if (SelStart.X=SelEnd.X) and (SelStart.Y=SelEnd.Y) then Exit;
  3719. Lock;
  3720. ey:=selend.y;
  3721. if selend.x=0 then
  3722. dec(ey);
  3723. for i:=selstart.y to ey do
  3724. begin
  3725. S:=GetLineText(i);
  3726. if (length(s)>1) and (S[1]=' ') then
  3727. Delete(s,1,1);
  3728. SetLineText(i,S);
  3729. end;
  3730. SetCurPtr(CurPos.X,CurPos.Y);
  3731. UpdateAttrsRange(SelStart.Y,SelEnd.Y,attrAll);
  3732. DrawLines(CurPos.Y);
  3733. SetModified(true);
  3734. UnLock;
  3735. end;
  3736. procedure TCustomCodeEditor.SelectWord;
  3737. const WordChars = ['A'..'Z','a'..'z','0'..'9','_'];
  3738. var S : String;
  3739. StartPos,EndPos : byte;
  3740. A,B: TPoint;
  3741. begin
  3742. A:=CurPos;
  3743. B:=CurPos;
  3744. S:=GetLineText(A.Y);
  3745. StartPos:=A.X+1;
  3746. EndPos:=StartPos;
  3747. if not (S[StartPos] in WordChars) then
  3748. exit
  3749. else
  3750. begin
  3751. While (StartPos>0) and (S[StartPos-1] in WordChars) do
  3752. Dec(StartPos);
  3753. While (EndPos<Length(S)) and (S[EndPos+1] in WordChars) do
  3754. Inc(EndPos);
  3755. A.X:=StartPos-1;
  3756. B.X:=EndPos;
  3757. SetSelection(A,B);
  3758. end;
  3759. end;
  3760. procedure TCustomCodeEditor.SelectLine;
  3761. var A,B: TPoint;
  3762. begin
  3763. if CurPos.Y<GetLineCount then
  3764. begin
  3765. A.Y:=CurPos.Y; A.X:=0;
  3766. B.Y:=CurPos.Y+1; B.X:=0;
  3767. SetSelection(A,B);
  3768. end;
  3769. end;
  3770. procedure TCustomCodeEditor.WriteBlock;
  3771. var FileName: string;
  3772. S: PBufStream;
  3773. begin
  3774. if ValidBlock=false then Exit;
  3775. FileName:='';
  3776. if EditorDialog(edWriteBlock, @FileName) <> cmCancel then
  3777. begin
  3778. FileName := FExpand(FileName);
  3779. New(S, Init(FileName, stCreate, 4096));
  3780. if (S=nil) or (S^.Status<>stOK) then
  3781. EditorDialog(edCreateError,@FileName)
  3782. else
  3783. if SaveAreaToStream(S,SelStart,SelEnd)=false then
  3784. EditorDialog(edWriteError,@FileName);
  3785. if Assigned(S) then Dispose(S, Done);
  3786. end;
  3787. end;
  3788. procedure TCustomCodeEditor.ReadBlock;
  3789. var FileName: string;
  3790. S: PBufStream;
  3791. E: PCodeEditor;
  3792. R: TRect;
  3793. begin
  3794. FileName:='';
  3795. if EditorDialog(edReadBlock, @FileName) <> cmCancel then
  3796. begin
  3797. FileName := FExpand(FileName);
  3798. New(S, Init(FileName, stOpenRead, 4096));
  3799. if (S=nil) or (S^.Status<>stOK) then
  3800. EditorDialog(edReadError,@FileName)
  3801. else
  3802. begin
  3803. R.Assign(0,0,0,0);
  3804. New(E, Init(R,nil,nil,nil,nil));
  3805. if E^.LoadFromStream(S)=false then
  3806. EditorDialog(edReadError,@FileName)
  3807. else
  3808. begin
  3809. E^.SelectAll(true);
  3810. Self.InsertFrom(E);
  3811. end;
  3812. Dispose(E, Done);
  3813. end;
  3814. if Assigned(S) then Dispose(S, Done);
  3815. end;
  3816. end;
  3817. procedure TCustomCodeEditor.PrintBlock;
  3818. begin
  3819. NotImplemented; Exit;
  3820. end;
  3821. procedure TCustomCodeEditor.ExpandCodeTemplate;
  3822. var Line,ShortCut: string;
  3823. X,Y,I,LineIndent: sw_integer;
  3824. CodeLines: PUnsortedStringCollection;
  3825. CanJump: boolean;
  3826. begin
  3827. {
  3828. The usage of editing primitives in this routine make it pretty slow, but
  3829. its speed is still acceptable and they make the implementation of Undo
  3830. much easier... - Gabor
  3831. }
  3832. if IsReadOnly then Exit;
  3833. Lock;
  3834. Line:=GetDisplayText(CurPos.Y);
  3835. X:=CurPos.X; ShortCut:='';
  3836. if X<=length(Line) then
  3837. while (X>0) and (Line[X] in (NumberChars+AlphaChars)) do
  3838. begin
  3839. ShortCut:=Line[X]+ShortCut;
  3840. Dec(X);
  3841. end;
  3842. if ShortCut<>'' then
  3843. begin
  3844. New(CodeLines, Init(10,10));
  3845. if TranslateCodeTemplate(ShortCut,CodeLines) then
  3846. begin
  3847. LineIndent:=X;
  3848. SetCurPtr(X,CurPos.Y);
  3849. for I:=1 to length(ShortCut) do
  3850. DelChar;
  3851. for Y:=0 to CodeLines^.Count-1 do
  3852. begin
  3853. CanJump:=false;
  3854. if Y>0 then
  3855. begin
  3856. CanJump:=Trim(GetLineText(CurPos.Y))='';
  3857. if CanJump=false then
  3858. begin
  3859. for X:=1 to LineIndent do { indent template lines to align }
  3860. AddChar(' '); { them to the first line }
  3861. end
  3862. else
  3863. SetCurPtr(CurPos.X+LineIndent,CurPos.Y);
  3864. end;
  3865. Line:=CodeLines^.At(Y)^;
  3866. for X:=1 to length(Line) do
  3867. AddChar(Line[X]);
  3868. if Y<CodeLines^.Count-1 then
  3869. begin
  3870. InsertNewLine; { line break }
  3871. if CanJump=false then
  3872. begin
  3873. while CurPos.X>0 do { unindent }
  3874. begin
  3875. SetCurPtr(CurPos.X-1,CurPos.Y);
  3876. DelChar;
  3877. end;
  3878. end
  3879. else
  3880. SetCurPtr(0,CurPos.Y);
  3881. end;
  3882. end;
  3883. end;
  3884. Dispose(CodeLines, Done);
  3885. end;
  3886. UnLock;
  3887. end;
  3888. procedure TCustomCodeEditor.AddChar(C: char);
  3889. const OpenBrackets : string[10] = '[({';
  3890. CloseBrackets : string[10] = '])}';
  3891. var S,SC,TabS: string;
  3892. BI: byte;
  3893. CI,TabStart,LocTabSize : Sw_integer;
  3894. SP: TPoint;
  3895. HoldUndo : boolean;
  3896. begin
  3897. if IsReadOnly then Exit;
  3898. Lock;
  3899. SP:=CurPos;
  3900. HoldUndo:=GetStoreUndo;
  3901. SetStoreUndo(false);
  3902. if (C<>TAB) or IsFlagSet(efUseTabCharacters) then
  3903. SC:=C
  3904. else
  3905. begin
  3906. LocTabSize:=GetTabSize - (CurPos.X mod GetTabSize);
  3907. if (CurPos.Y<=1) or not IsFlagSet(efAutoIndent) then
  3908. SC:=CharStr(' ',LocTabSize)
  3909. else
  3910. begin
  3911. S:=GetLineText(CurPos.Y-1);
  3912. BI:=CurPos.X+1;
  3913. while (BI<=Length(S)) and (S[BI]=' ') do
  3914. inc(BI);
  3915. if (BI=CurPos.X+1) or (BI>Length(S)) then
  3916. SC:=CharStr(' ',LocTabSize)
  3917. else
  3918. SC:=CharStr(' ',BI-CurPos.X-1);
  3919. end;
  3920. end;
  3921. S:=GetLineText(CurPos.Y);
  3922. if CharIdxToLinePos(CurPos.Y,length(S))<CurPos.X then
  3923. begin
  3924. S:=S+CharStr(' ',CurPos.X-CharIdxToLinePos(CurPos.Y,length(S)){-1});
  3925. SetLineText(CurPos.Y,S);
  3926. end;
  3927. CI:=LinePosToCharIdx(CurPos.Y,CurPos.X);
  3928. if (CI>0) and (S[CI]=TAB) then
  3929. begin
  3930. if CI=1 then
  3931. TabStart:=0
  3932. else
  3933. TabStart:=CharIdxToLinePos(CurPos.Y,CI-1)+1;
  3934. if SC=Tab then TabS:=Tab else
  3935. TabS:=CharStr(' ',CurPos.X-TabStart);
  3936. SetLineText(CurPos.Y,copy(S,1,CI-1)+TabS+SC+copy(S,CI+1,255));
  3937. SetCurPtr(CharIdxToLinePos(CurPos.Y,CI+length(TabS)+length(SC)),CurPos.Y);
  3938. end
  3939. else
  3940. begin
  3941. if Overwrite and (CI<=length(S)) then
  3942. SetLineText(CurPos.Y,copy(S,1,CI-1)+SC+copy(S,CI+length(SC),255))
  3943. else
  3944. SetLineText(CurPos.Y,copy(S,1,CI-1)+SC+copy(S,CI,255));
  3945. SetCurPtr(CharIdxToLinePos(CurPos.Y,CI+length(SC)),CurPos.Y);
  3946. end;
  3947. {$ifdef Undo}
  3948. { must be before CloseBrackets !! }
  3949. SetStoreUndo(HoldUndo);
  3950. Addaction(eaInsertText,SP,CurPos,C);
  3951. SetStoreUndo(false);
  3952. {$endif Undo}
  3953. if IsFlagSet(efAutoBrackets) then
  3954. begin
  3955. BI:=Pos(C,OpenBrackets);
  3956. if (BI>0) then
  3957. begin
  3958. SetStoreUndo(HoldUndo);
  3959. AddChar(CloseBrackets[BI]);
  3960. SetStoreUndo(false);
  3961. SetCurPtr(CurPos.X-1,CurPos.Y);
  3962. end;
  3963. end;
  3964. UpdateAttrs(CurPos.Y,attrAll);
  3965. AdjustSelection(CurPos.X-SP.X,CurPos.Y-SP.Y);
  3966. DrawLines(CurPos.Y);
  3967. SetStoreUndo(HoldUndo);
  3968. SetModified(true);
  3969. UnLock;
  3970. end;
  3971. {$ifdef WinClipSupported}
  3972. function TCustomCodeEditor.ClipPasteWin: Boolean;
  3973. var OK: boolean;
  3974. l,i : longint;
  3975. p,p10,p2,p13 : pchar;
  3976. s : string;
  3977. BPos,EPos,StorePos : TPoint;
  3978. first : boolean;
  3979. begin
  3980. Lock;
  3981. OK:=WinClipboardSupported;
  3982. if OK then
  3983. begin
  3984. first:=true;
  3985. StorePos:=CurPos;
  3986. i:=CurPos.Y;
  3987. l:=GetTextWinClipboardSize;
  3988. if l=0 then
  3989. OK:=false
  3990. else
  3991. OK:=GetTextWinClipBoardData(p,l);
  3992. if OK then
  3993. begin
  3994. AddGroupedAction(eaPasteWin);
  3995. p2:=p;
  3996. p13:=strpos(p,#13);
  3997. p10:=strpos(p,#10);
  3998. while assigned(p10) do
  3999. begin
  4000. if p13+1=p10 then
  4001. p13[0]:=#0
  4002. else
  4003. p10[0]:=#0;
  4004. s:=strpas(p2);
  4005. if first then
  4006. begin
  4007. { we need to cut the line in two
  4008. if not at end of line PM }
  4009. InsertNewLine;
  4010. SetCurPtr(StorePos.X,StorePos.Y);
  4011. InsertText(s);
  4012. first:=false;
  4013. end
  4014. else
  4015. begin
  4016. Inc(i);
  4017. InsertLine(i,s);
  4018. BPos.X:=0;BPos.Y:=i;
  4019. EPOS.X:=Length(s);EPos.Y:=i;
  4020. AddAction(eaInsertLine,BPos,EPos,S);
  4021. end;
  4022. if p13+1=p10 then
  4023. p13[0]:=#13
  4024. else
  4025. p10[0]:=#10;
  4026. p2:=@p10[1];
  4027. p13:=strpos(p2,#13);
  4028. p10:=strpos(p2,#10);
  4029. end;
  4030. if strlen(p2)>0 then
  4031. begin
  4032. s:=strpas(p2);
  4033. if not first then
  4034. SetCurPtr(0,i+1);
  4035. InsertText(s);
  4036. end;
  4037. SetCurPtr(StorePos.X,StorePos.Y);
  4038. SetModified(true);
  4039. UpdateAttrs(StorePos.Y,attrAll);
  4040. CloseGroupedAction(eaPasteWin);
  4041. Update;
  4042. { we must free the allocated memory }
  4043. freemem(p,l);
  4044. end;
  4045. end;
  4046. ClipPasteWin:=OK;
  4047. UnLock;
  4048. end;
  4049. function TCustomCodeEditor.ClipCopyWin: Boolean;
  4050. var OK: boolean;
  4051. p,p2 : pchar;
  4052. s : string;
  4053. i,str_begin,str_end,NumLines,PcLength : longint;
  4054. begin
  4055. NumLines:=SelEnd.Y-SelStart.Y;
  4056. if (NumLines>0) or (SelEnd.X>SelStart.X) then
  4057. Inc(NumLines);
  4058. if NumLines=0 then
  4059. exit;
  4060. Lock;
  4061. { First calculate needed size }
  4062. { for newlines first + 1 for terminal #0 }
  4063. PcLength:=Length(EOL)*(NumLines-1)+1;
  4064. { overestimated but can not be that big PM }
  4065. for i:=SelStart.Y to SelEnd.Y do
  4066. PCLength:=PCLength+Length(GetLineText(i));
  4067. getmem(p,PCLength);
  4068. i:=SelStart.Y;
  4069. s:=GetLineText(i);
  4070. str_begin:=LinePosToCharIdx(i,SelStart.X);
  4071. if SelEnd.Y>SelStart.Y then
  4072. str_end:=255
  4073. else
  4074. str_end:=LinePosToCharIdx(i,SelEnd.X)-1;
  4075. s:=copy(s,str_begin,str_end-str_begin+1);
  4076. strpcopy(p,s);
  4077. p2:=strend(p);
  4078. inc(i);
  4079. while i<SelEnd.Y do
  4080. begin
  4081. strpcopy(p2,EOL+GetLineText(i));
  4082. p2:=strend(p2);
  4083. Inc(i);
  4084. end;
  4085. if SelEnd.Y>SelStart.Y then
  4086. begin
  4087. s:=copy(GetLineText(i),1,LinePosToCharIdx(i,SelEnd.X)-1);
  4088. strpcopy(p2,EOL+s);
  4089. end;
  4090. OK:=WinClipboardSupported;
  4091. if OK then
  4092. begin
  4093. OK:=SetTextWinClipBoardData(p,strlen(p));
  4094. end;
  4095. ClipCopyWin:=OK;
  4096. Freemem(p,PCLength);
  4097. UnLock;
  4098. end;
  4099. {$endif WinClipSupported}
  4100. function TCustomCodeEditor.ClipCopy: Boolean;
  4101. var OK: boolean;
  4102. begin
  4103. Lock;
  4104. {AddGroupedAction(eaCopy);
  4105. can we undo a copy ??
  4106. maybe as an Undo Paste in Clipboard !! }
  4107. OK:=Clipboard<>nil;
  4108. if OK then OK:=Clipboard^.InsertFrom(@Self);
  4109. ClipCopy:=OK;
  4110. UnLock;
  4111. end;
  4112. procedure TCustomCodeEditor.ClipCut;
  4113. begin
  4114. if IsReadOnly then Exit;
  4115. Lock;
  4116. AddGroupedAction(eaCut);
  4117. DontConsiderShiftState:=true;
  4118. if Clipboard<>nil then
  4119. if Clipboard^.InsertFrom(@Self) then
  4120. begin
  4121. if not IsClipBoard then
  4122. DelSelect;
  4123. SetModified(true);
  4124. end;
  4125. CloseGroupedAction(eaCut);
  4126. UnLock;
  4127. DontConsiderShiftState:=false;
  4128. end;
  4129. procedure TCustomCodeEditor.ClipPaste;
  4130. begin
  4131. if IsReadOnly then Exit;
  4132. DontConsiderShiftState:=true;
  4133. Lock;
  4134. AddGroupedAction(eaPaste);
  4135. if Clipboard<>nil then
  4136. begin
  4137. InsertFrom(Clipboard);
  4138. SetModified(true);
  4139. end;
  4140. CloseGroupedAction(eaPaste);
  4141. UnLock;
  4142. DontConsiderShiftState:=false;
  4143. end;
  4144. procedure TCustomCodeEditor.Undo;
  4145. begin
  4146. NotImplemented; Exit;
  4147. end;
  4148. procedure TCustomCodeEditor.Redo;
  4149. begin
  4150. NotImplemented; Exit;
  4151. end;
  4152. procedure TCustomCodeEditor.GotoLine;
  4153. var
  4154. GotoRec: TGotoLineDialogRec;
  4155. begin
  4156. with GotoRec do
  4157. begin
  4158. LineNo:='1';
  4159. Lines:=GetLineCount;
  4160. if EditorDialog(edGotoLine, @GotoRec) <> cmCancel then
  4161. begin
  4162. SetCurPtr(0,StrToInt(LineNo)-1);
  4163. TrackCursor(true);
  4164. end;
  4165. end;
  4166. end;
  4167. procedure TCustomCodeEditor.Find;
  4168. var
  4169. FindRec: TFindDialogRec;
  4170. DoConf: boolean;
  4171. begin
  4172. with FindRec do
  4173. begin
  4174. Find := FindStr;
  4175. if GetCurrentWord<>'' then
  4176. Find:=GetCurrentWord;
  4177. Options := (FindFlags and ffmOptions) shr ffsOptions;
  4178. Direction := (FindFlags and ffmDirection) shr ffsDirection;
  4179. Scope := (FindFlags and ffmScope) shr ffsScope;
  4180. Origin := (FindFlags and ffmOrigin) shr ffsOrigin;
  4181. DoConf:= (FindFlags and ffPromptOnReplace)<>0;
  4182. if EditorDialog(edFind, @FindRec) <> cmCancel then
  4183. begin
  4184. FindStr := Find;
  4185. FindFlags := (Options shl ffsOptions) or (Direction shl ffsDirection) or
  4186. (Scope shl ffsScope) or (Origin shl ffsOrigin);
  4187. FindFlags := FindFlags and not ffDoReplace;
  4188. if DoConf then
  4189. FindFlags := (FindFlags or ffPromptOnReplace);
  4190. SearchRunCount:=0;
  4191. DoSearchReplace;
  4192. end;
  4193. end;
  4194. end;
  4195. procedure TCustomCodeEditor.Replace;
  4196. var
  4197. ReplaceRec: TReplaceDialogRec;
  4198. Re: word;
  4199. begin
  4200. if IsReadOnly then Exit;
  4201. with ReplaceRec do
  4202. begin
  4203. Find := FindStr;
  4204. if GetCurrentWord<>'' then
  4205. Find:=GetCurrentWord;
  4206. Replace := ReplaceStr;
  4207. Options := (FindFlags and ffmOptions) shr ffsOptions;
  4208. Direction := (FindFlags and ffmDirection) shr ffsDirection;
  4209. Scope := (FindFlags and ffmScope) shr ffsScope;
  4210. Origin := (FindFlags and ffmOrigin) shr ffsOrigin;
  4211. Re:=EditorDialog(edReplace, @ReplaceRec);
  4212. if Re <> cmCancel then
  4213. begin
  4214. FindStr := Find;
  4215. ReplaceStr := Replace;
  4216. FindFlags := (Options shl ffsOptions) or (Direction shl ffsDirection) or
  4217. (Scope shl ffsScope) or (Origin shl ffsOrigin);
  4218. FindFlags := FindFlags or ffDoReplace;
  4219. if Re = cmYes then
  4220. FindFlags := FindFlags or ffReplaceAll;
  4221. SearchRunCount:=0;
  4222. DoSearchReplace;
  4223. end;
  4224. end;
  4225. end;
  4226. procedure TCustomCodeEditor.DoSearchReplace;
  4227. var S: string;
  4228. DX,DY,P,Y,X: sw_integer;
  4229. Count: sw_integer;
  4230. Found,CanExit: boolean;
  4231. SForward,DoReplace,DoReplaceAll: boolean;
  4232. LeftOK,RightOK: boolean;
  4233. FoundCount: sw_integer;
  4234. A,B: TPoint;
  4235. AreaStart,AreaEnd: TPoint;
  4236. CanReplace,Confirm: boolean;
  4237. Re: word;
  4238. IFindStr : string;
  4239. BT : BTable;
  4240. function ContainsText(const SubS:string;var S: string; Start: Sw_word): Sw_integer;
  4241. var
  4242. P: Sw_Integer;
  4243. begin
  4244. if Start<=0 then
  4245. P:=0
  4246. else
  4247. begin
  4248. if SForward then
  4249. begin
  4250. if Start>length(s) then
  4251. P:=0
  4252. else if FindFlags and ffCaseSensitive<>0 then
  4253. P:=BMFScan(S[Start],length(s)+1-Start,FindStr,Bt)+1
  4254. else
  4255. P:=BMFIScan(S[Start],length(s)+1-Start,IFindStr,Bt)+1;
  4256. if P>0 then
  4257. Inc(P,Start-1);
  4258. end
  4259. else
  4260. begin
  4261. if start>length(s) then
  4262. start:=length(s);
  4263. if FindFlags and ffCaseSensitive<>0 then
  4264. P:=BMBScan(S[1],Start,FindStr,Bt)+1
  4265. else
  4266. P:=BMBIScan(S[1],Start,IFindStr,Bt)+1;
  4267. end;
  4268. end;
  4269. ContainsText:=P;
  4270. end;
  4271. function InArea(X,Y: sw_integer): boolean;
  4272. begin
  4273. InArea:=((AreaStart.Y=Y) and (AreaStart.X<=X)) or
  4274. ((AreaStart.Y<Y) and (Y<AreaEnd.Y)) or
  4275. ((AreaEnd.Y=Y) and (X<=AreaEnd.X));
  4276. end;
  4277. var CurDY: sw_integer;
  4278. begin
  4279. Inc(SearchRunCount);
  4280. SForward:=(FindFlags and ffmDirection)=ffForward;
  4281. DoReplace:=(FindFlags and ffDoReplace)<>0;
  4282. Confirm:=(FindFlags and ffPromptOnReplace)<>0;
  4283. DoReplaceAll:=(FindFlags and ffReplaceAll)<>0;
  4284. Count:=GetLineCount; FoundCount:=0;
  4285. if SForward then
  4286. DY:=1
  4287. else
  4288. DY:=-1;
  4289. DX:=DY;
  4290. if (FindFlags and ffmScope)=ffGlobal then
  4291. begin
  4292. AreaStart.X:=0;
  4293. AreaStart.Y:=0;
  4294. AreaEnd.X:=length(GetDisplayText(Count-1));
  4295. AreaEnd.Y:=Count-1;
  4296. end
  4297. else
  4298. begin
  4299. AreaStart:=SelStart;
  4300. AreaEnd:=SelEnd;
  4301. end;
  4302. X:=CurPos.X-DX;
  4303. Y:=CurPos.Y;;
  4304. if SearchRunCount=1 then
  4305. if (FindFlags and ffmOrigin)=ffEntireScope then
  4306. if SForward then
  4307. begin
  4308. X:=AreaStart.X-1;
  4309. Y:=AreaStart.Y;
  4310. end
  4311. else
  4312. begin
  4313. X:=AreaEnd.X+1;
  4314. Y:=AreaEnd.Y;
  4315. end;
  4316. if FindFlags and ffCaseSensitive<>0 then
  4317. begin
  4318. if SForward then
  4319. BMFMakeTable(FindStr,bt)
  4320. else
  4321. BMBMakeTable(FindStr,bt);
  4322. end
  4323. else
  4324. begin
  4325. IFindStr:=Upper(FindStr);
  4326. if SForward then
  4327. BMFMakeTable(IFindStr,bt)
  4328. else
  4329. BMBMakeTable(IFindStr,bt);
  4330. end;
  4331. inc(X,DX);
  4332. CanExit:=false;
  4333. if (DoReplace=false) or ((Confirm=false) and (Owner<>nil)) then
  4334. Owner^.Lock;
  4335. if InArea(X,Y) then
  4336. repeat
  4337. CurDY:=DY;
  4338. S:=GetDisplayText(Y);
  4339. P:=ContainsText(FindStr,S,X+1);
  4340. Found:=P<>0;
  4341. if Found then
  4342. begin
  4343. A.X:=P-1;
  4344. A.Y:=Y;
  4345. B.Y:=Y;
  4346. B.X:=A.X+length(FindStr);
  4347. end;
  4348. Found:=Found and InArea(A.X,A.Y);
  4349. if Found and ((FindFlags and ffWholeWordsOnly)<>0) then
  4350. begin
  4351. LeftOK:=(A.X<=0) or (not( (S[A.X] in AlphaChars) or (S[A.X] in NumberChars) ));
  4352. RightOK:=(B.X>=length(S)) or (not( (S[B.X+1] in AlphaChars) or (S[B.X+1] in NumberChars) ));
  4353. Found:=LeftOK and RightOK;
  4354. if Found=false then
  4355. begin
  4356. CurDY:=0;
  4357. X:=B.X+1;
  4358. end;
  4359. end;
  4360. if Found then
  4361. Inc(FoundCount);
  4362. if Found then
  4363. begin
  4364. Lock;
  4365. if SForward then
  4366. SetCurPtr(B.X,B.Y)
  4367. else
  4368. SetCurPtr(A.X,A.Y);
  4369. TrackCursor(true);
  4370. SetHighlight(A,B);
  4371. UnLock;
  4372. CurDY:=0;
  4373. if (DoReplace=false) then
  4374. begin
  4375. CanExit:=true;
  4376. If SForward then
  4377. begin
  4378. X:=B.X;
  4379. Y:=B.Y;
  4380. end
  4381. else
  4382. begin
  4383. X:=A.X;
  4384. Y:=A.Y;
  4385. end;
  4386. end
  4387. else
  4388. begin
  4389. if Confirm=false then CanReplace:=true else
  4390. begin
  4391. Re:=EditorDialog(edReplacePrompt,@CurPos);
  4392. case Re of
  4393. cmYes :
  4394. CanReplace:=true;
  4395. cmNo :
  4396. CanReplace:=false;
  4397. else {cmCancel}
  4398. begin
  4399. CanReplace:=false;
  4400. CanExit:=true;
  4401. end;
  4402. end;
  4403. end;
  4404. if CanReplace then
  4405. begin
  4406. Lock;
  4407. SetSelection(A,B);
  4408. DelSelect;
  4409. InsertText(ReplaceStr);
  4410. if SForward then
  4411. begin
  4412. X:=CurPos.X;
  4413. Y:=CurPos.Y;
  4414. end
  4415. else
  4416. begin
  4417. X:=A.X;
  4418. Y:=A.Y;
  4419. end;
  4420. UnLock;
  4421. end
  4422. else
  4423. begin
  4424. If SForward then
  4425. begin
  4426. X:=B.X;
  4427. Y:=B.Y;
  4428. end
  4429. else
  4430. begin
  4431. X:=A.X;
  4432. Y:=A.Y;
  4433. end;
  4434. end;
  4435. if (DoReplaceAll=false) then
  4436. CanExit:=true;
  4437. end;
  4438. end;
  4439. if (CanExit=false) and (CurDY<>0) then
  4440. begin
  4441. inc(Y,CurDY);
  4442. if SForward then
  4443. X:=0
  4444. else
  4445. X:=254;
  4446. CanExit:=(Y>=Count) or (Y<0);
  4447. end;
  4448. if not CanExit then
  4449. CanExit:=not InArea(X,Y);
  4450. until CanExit;
  4451. if (FoundCount=0) or (DoReplace) then
  4452. SetHighlight(CurPos,CurPos);
  4453. if (DoReplace=false) or ((Confirm=false) and (Owner<>nil)) then
  4454. Owner^.UnLock;
  4455. {if (DoReplace=false) or (Confirm=false) then
  4456. UnLock;}
  4457. if (FoundCount=0) then
  4458. EditorDialog(edSearchFailed,nil);
  4459. if (FindFlags and ffmScope)=ffSelectedText then
  4460. { restore selection PM }
  4461. begin
  4462. SetSelection(AreaStart,AreaEnd);
  4463. end;
  4464. end;
  4465. function TCustomCodeEditor.GetInsertMode: boolean;
  4466. begin
  4467. GetInsertMode:=(GetFlags and efInsertMode)<>0;
  4468. end;
  4469. procedure TCustomCodeEditor.SetInsertMode(InsertMode: boolean);
  4470. begin
  4471. if InsertMode then
  4472. SetFlags(GetFlags or efInsertMode)
  4473. else
  4474. SetFlags(GetFlags and (not efInsertMode));
  4475. DrawCursor;
  4476. end;
  4477. { there is a problem with ShiftDel here
  4478. because GetShitState tells to extend the
  4479. selection which gives wrong results (PM) }
  4480. function TCustomCodeEditor.ShouldExtend: boolean;
  4481. var ShiftInEvent: boolean;
  4482. begin
  4483. ShiftInEvent:=false;
  4484. if Assigned(CurEvent) then
  4485. if CurEvent^.What=evKeyDown then
  4486. ShiftInEvent:=((CurEvent^.KeyShift and kbShift)<>0);
  4487. ShouldExtend:=ShiftInEvent and
  4488. not DontConsiderShiftState;
  4489. end;
  4490. procedure TCustomCodeEditor.SetCurPtr(X,Y: sw_integer);
  4491. var OldPos,OldSEnd,OldSStart: TPoint;
  4492. Extended: boolean;
  4493. begin
  4494. Lock;
  4495. X:=Max(0,Min(MaxLineLength+1,X));
  4496. Y:=Max(0,Min(GetLineCount-1,Y));
  4497. OldPos:=CurPos;
  4498. OldSEnd:=SelEnd;
  4499. OldSStart:=SelStart;
  4500. CurPos.X:=X;
  4501. CurPos.Y:=Y;
  4502. TrackCursor(false);
  4503. if (NoSelect=false) and (ShouldExtend) then
  4504. begin
  4505. CheckSels;
  4506. Extended:=false;
  4507. if PointOfs(OldPos)=PointOfs(SelStart) then
  4508. begin SetSelection(CurPos,SelEnd); Extended:=true; end;
  4509. CheckSels;
  4510. if Extended=false then
  4511. if PointOfs(OldPos)=PointOfs(SelEnd) then
  4512. begin
  4513. if ValidBlock=false then
  4514. SetSelection(CurPos,CurPos);
  4515. SetSelection(SelStart,CurPos); Extended:=true;
  4516. end;
  4517. CheckSels;
  4518. if (Extended=false) then
  4519. if PointOfs(OldPos)<=PointOfs(CurPos)
  4520. then begin SetSelection(OldPos,CurPos); Extended:=true; end
  4521. else begin SetSelection(CurPos,OldPos); Extended:=true; end;
  4522. DrawView;
  4523. end else
  4524. if not IsFlagSet(efPersistentBlocks) then
  4525. begin HideSelect; DrawView; end;
  4526. { if PointOfs(SelStart)=PointOfs(SelEnd) then
  4527. SetSelection(CurPos,CurPos);}
  4528. if (GetFlags and (efHighlightColumn+efHighlightRow))<>0 then
  4529. DrawView;
  4530. if ((CurPos.X<>OldPos.X) or (CurPos.Y<>OldPos.Y)) and
  4531. ((Highlight.A.X<>HighLight.B.X) or (Highlight.A.Y<>HighLight.B.Y)) then
  4532. HideHighlight;
  4533. if (OldPos.Y<>CurPos.Y) and (0<=OldPos.Y) and (OldPos.Y<GetLineCount) then
  4534. SetLineText(OldPos.Y,RTrim(GetLineText(OldPos.Y),not IsFlagSet(efUseTabCharacters)));
  4535. if ((CurPos.X<>OldPos.X) or (CurPos.Y<>OldPos.Y)) and (GetErrorMessage<>'') then
  4536. SetErrorMessage('');
  4537. { if ((CurPos.X<>OldPos.X) or (CurPos.Y<>OldPos.Y)) and (HighlightRow<>-1) then
  4538. SetHighlightRow(-1);}
  4539. if ((CurPos.X<>OldPos.X) or (CurPos.Y<>OldPos.Y)) then
  4540. AddAction(eaMoveCursor,OldPos,CurPos,'');
  4541. if ((CurPos.X<>OldPos.X) or (CurPos.Y<>OldPos.Y)) then
  4542. PositionChanged;{UpdateIndicator;}
  4543. UnLock;
  4544. end;
  4545. procedure TCustomCodeEditor.CheckSels;
  4546. begin
  4547. if (SelStart.Y>SelEnd.Y) or
  4548. ( (SelStart.Y=SelEnd.Y) and (SelStart.X>SelEnd.X) ) then
  4549. SetSelection(SelEnd,SelStart);
  4550. end;
  4551. procedure TCustomCodeEditor.CodeCompleteApply;
  4552. var S: string;
  4553. I: integer;
  4554. begin
  4555. Lock;
  4556. { here should be some kind or "mark" or "break" inserted in the Undo
  4557. information, so activating it "undoes" only the completition first and
  4558. doesn't delete the complete word at once... - Gabor }
  4559. S:=GetCodeCompleteFrag;
  4560. SetCurPtr(CurPos.X-length(S),CurPos.Y);
  4561. for I:=1 to length(S) do
  4562. DelChar;
  4563. S:=GetCodeCompleteWord;
  4564. for I:=1 to length(S) do
  4565. AddChar(S[I]);
  4566. UnLock;
  4567. SetCompleteState(csInactive);
  4568. end;
  4569. procedure TCustomCodeEditor.CodeCompleteCancel;
  4570. begin
  4571. SetCompleteState(csDenied);
  4572. end;
  4573. procedure TCustomCodeEditor.CodeCompleteCheck;
  4574. var Line: string;
  4575. X: sw_integer;
  4576. CurWord,NewWord: string;
  4577. begin
  4578. SetCodeCompleteFrag('');
  4579. if (not IsFlagSet(efCodeComplete)) or (IsReadOnly=true) then Exit;
  4580. Lock;
  4581. Line:=GetDisplayText(CurPos.Y);
  4582. X:=CurPos.X; CurWord:='';
  4583. if X<=length(Line) then
  4584. while (X>0) and (Line[X] in (NumberChars+AlphaChars)) do
  4585. begin
  4586. CurWord:=Line[X]+CurWord;
  4587. Dec(X);
  4588. end;
  4589. if (length(CurWord)>=CodeCompleteMinLen) and CompleteCodeWord(CurWord,NewWord) then
  4590. begin
  4591. SetCodeCompleteFrag(CurWord);
  4592. SetCodeCompleteWord(NewWord);
  4593. end
  4594. else
  4595. ClearCodeCompleteWord;
  4596. UnLock;
  4597. end;
  4598. function TCustomCodeEditor.GetCodeCompleteFrag: string;
  4599. begin
  4600. { Abstract }
  4601. GetCodeCompleteFrag:='';
  4602. end;
  4603. procedure TCustomCodeEditor.SetCodeCompleteFrag(const S: string);
  4604. begin
  4605. { Abstract }
  4606. end;
  4607. procedure TCustomCodeEditor.DrawLines(FirstLine: sw_integer);
  4608. begin
  4609. if FirstLine>=(Delta.Y+Size.Y) then Exit; { falls outside of the screen }
  4610. DrawView;
  4611. end;
  4612. procedure TCustomCodeEditor.HideHighlight;
  4613. begin
  4614. SetHighlight(CurPos,CurPos);
  4615. end;
  4616. function TCustomCodeEditor.ValidBlock: boolean;
  4617. begin
  4618. ValidBlock:=(SelStart.X<>SelEnd.X) or (SelStart.Y<>SelEnd.Y);
  4619. end;
  4620. procedure TCustomCodeEditor.SetSelection(A, B: TPoint);
  4621. var WV: boolean;
  4622. OS,OE: TPoint;
  4623. begin
  4624. WV:=ValidBlock;
  4625. OS:=SelStart; OE:=SelEnd;
  4626. SelStart:=A; SelEnd:=B;
  4627. if (WV=false) and (ValidBlock=false) then { do nothing } else
  4628. if (OS.X<>SelStart.X) or (OS.Y<>SelStart.Y) or
  4629. (OE.X<>SelEnd.X) or (OE.Y<>SelEnd.Y) then
  4630. SelectionChanged;
  4631. end;
  4632. procedure TCustomCodeEditor.SetHighlight(A, B: TPoint);
  4633. begin
  4634. Highlight.A:=A; Highlight.B:=B;
  4635. HighlightChanged;
  4636. end;
  4637. {procedure TCustomCodeEditor.SetHighlightRow(Row: sw_integer);
  4638. begin
  4639. HighlightRow:=Row;
  4640. DrawView;
  4641. end;}
  4642. {procedure TCodeEditor.SetDebuggerRow(Row: sw_integer);
  4643. begin
  4644. DebuggerRow:=Row;
  4645. DrawView;
  4646. end;}
  4647. procedure TCustomCodeEditor.SelectAll(Enable: boolean);
  4648. var A,B: TPoint;
  4649. begin
  4650. if (Enable=false) or (GetLineCount=0) then
  4651. begin A:=CurPos; B:=CurPos end
  4652. else
  4653. begin
  4654. A.X:=0; A.Y:=0;
  4655. { B.Y:=GetLineCount-1;
  4656. B.X:=length(GetLineText(B.Y));}
  4657. B.Y:=GetLineCount; B.X:=0;
  4658. end;
  4659. SetSelection(A,B);
  4660. DrawView;
  4661. end;
  4662. procedure TCustomCodeEditor.SelectionChanged;
  4663. var Enable,CanPaste: boolean;
  4664. begin
  4665. if GetLineCount=0 then
  4666. begin
  4667. SelStart.X:=0; SelStart.Y:=0; SelEnd:=SelStart;
  4668. end
  4669. else
  4670. if SelEnd.Y>GetLineCount-1 then
  4671. if (SelEnd.Y<>GetLineCount) or (SelEnd.X<>0) then
  4672. begin
  4673. SelEnd.Y:=GetLineCount-1;
  4674. SelEnd.X:=length(GetDisplayText(SelEnd.Y));
  4675. end;
  4676. Enable:=((SelStart.X<>SelEnd.X) or (SelStart.Y<>SelEnd.Y)) and (Clipboard<>nil);
  4677. SetCmdState(ToClipCmds,Enable and (Clipboard<>@Self));
  4678. SetCmdState(NulClipCmds,Enable);
  4679. CanPaste:=(Clipboard<>nil) and ((Clipboard^.SelStart.X<>Clipboard^.SelEnd.X) or
  4680. (Clipboard^.SelStart.Y<>Clipboard^.SelEnd.Y));
  4681. SetCmdState(FromClipCmds,CanPaste and (Clipboard<>@Self));
  4682. {$ifdef WinClipSupported}
  4683. SetCmdState(FromWinClipCmds,GetTextWinClipboardSize>0);
  4684. {$endif WinClipSupported}
  4685. SetCmdState(UndoCmd,(GetUndoActionCount>0));
  4686. SetCmdState(RedoCmd,(GetRedoActionCount>0));
  4687. Message(Application,evBroadcast,cmCommandSetChanged,nil);
  4688. DrawView;
  4689. end;
  4690. procedure TCustomCodeEditor.HighlightChanged;
  4691. begin
  4692. DrawView;
  4693. end;
  4694. procedure TCustomCodeEditor.SetState(AState: Word; Enable: Boolean);
  4695. procedure ShowSBar(SBar: PScrollBar);
  4696. begin
  4697. if Assigned(SBar) and (SBar^.GetState(sfVisible)=false) then
  4698. SBar^.Show;
  4699. end;
  4700. begin
  4701. inherited SetState(AState,Enable);
  4702. if AlwaysShowScrollBars then
  4703. begin
  4704. ShowSBar(HScrollBar);
  4705. ShowSBar(VScrollBar);
  4706. end;
  4707. if (AState and (sfActive+sfSelected+sfFocused))<>0 then
  4708. begin
  4709. SelectionChanged;
  4710. if ((State and sfFocused)=0) and (GetCompleteState=csOffering) then
  4711. ClearCodeCompleteWord;
  4712. end;
  4713. end;
  4714. function TCustomCodeEditor.GetPalette: PPalette;
  4715. const P: string[length(CEditor)] = CEditor;
  4716. begin
  4717. GetPalette:=@P;
  4718. end;
  4719. function TCustomCodeEditorCore.LoadFromStream(Editor: PCustomCodeEditor; Stream: PStream): boolean;
  4720. var S: string;
  4721. AllLinesComplete,LineComplete,OK: boolean;
  4722. begin
  4723. DeleteAllLines;
  4724. ChangedLine:=-1;
  4725. AllLinesComplete:=true;
  4726. OK:=(Stream^.Status=stOK);
  4727. if eofstream(Stream) then
  4728. AddLine('')
  4729. else
  4730. while OK and (eofstream(Stream)=false) and (GetLineCount<MaxLineCount) do
  4731. begin
  4732. ReadlnFromStream(Stream,S,LineComplete);
  4733. AllLinesComplete:=AllLinesComplete and LineComplete;
  4734. OK:=OK and (Stream^.Status=stOK);
  4735. if OK then AddLine(S);
  4736. if not LineComplete and (ChangedLine=-1) then
  4737. ChangedLine:=GetLineCount;
  4738. end;
  4739. LimitsChanged;
  4740. if not AllLinesComplete then
  4741. SetModified(true);
  4742. if (GetLineCount=MaxLineCount) and not eofstream(stream) then
  4743. EditorDialog(edTooManyLines,nil);
  4744. LoadFromStream:=OK;
  4745. end;
  4746. function TCustomCodeEditorCore.SaveAreaToStream(Editor: PCustomCodeEditor; Stream: PStream; StartP,EndP: TPoint): boolean;
  4747. var S: string;
  4748. OK: boolean;
  4749. Line: Sw_integer;
  4750. P: PCustomLine;
  4751. begin
  4752. if EndP.X=0 then
  4753. begin
  4754. if EndP.Y>0 then
  4755. begin
  4756. EndP.X:=length(GetDisplayText(EndP.Y));
  4757. end
  4758. else
  4759. EndP.X:=0;
  4760. end
  4761. else
  4762. Dec(EndP.X);
  4763. OK:=(Stream^.Status=stOK); Line:=StartP.Y;
  4764. while OK and (Line<=EndP.Y) and (Line<GetLineCount) do
  4765. begin
  4766. P:=GetLine(Line);
  4767. S:=P^.GetText;
  4768. { Remove all traling spaces PM }
  4769. if not Editor^.IsFlagSet(efKeepTrailingSpaces) then
  4770. While (Length(S)>0) and (S[Length(S)]=' ') do
  4771. Dec(S[0]);
  4772. { if FlagSet(efUseTabCharacters) then
  4773. S:=CompressUsingTabs(S,TabSize);
  4774. }
  4775. if Line=EndP.Y then S:=copy(S,1,LinePosToCharIdx(Line,EndP.X));
  4776. if Line=StartP.Y then S:=copy(S,LinePosToCharIdx(Line,StartP.X),255);
  4777. Stream^.Write(S[1],length(S));
  4778. if Line<EndP.Y then
  4779. Stream^.Write(EOL[1],length(EOL));
  4780. Inc(Line);
  4781. OK:=OK and (Stream^.Status=stOK);
  4782. end;
  4783. SaveAreaToStream:=OK;
  4784. end;
  4785. {$ifdef Undo}
  4786. constructor TEditorAction.init(act:byte; StartP,EndP:TPoint;Txt:String);
  4787. begin
  4788. Action:=act;
  4789. StartPos:=StartP;
  4790. EndPos:=EndP;
  4791. Text:=NewStr(txt);
  4792. ActionCount:=0;
  4793. end;
  4794. constructor TEditorAction.init_group(act:byte);
  4795. begin
  4796. Action:=act;
  4797. ActionCount:=0;
  4798. end;
  4799. function TEditorAction.Is_grouped_action : boolean;
  4800. begin
  4801. Is_grouped_action:=Action in [eaCut,eaPaste,eaPasteWin,eaClear];
  4802. end;
  4803. destructor TEditorAction.done;
  4804. begin
  4805. DisposeStr(Text);
  4806. end;
  4807. {$else}
  4808. procedure TEditorActionCollection.FreeItem(Item: Pointer);
  4809. begin
  4810. if assigned(Item) then
  4811. freemem(Item,Sizeof(TEditorAction));
  4812. end;
  4813. {$endif Undo}
  4814. function TEditorActionCollection.At(Idx : sw_integer) : PEditorAction;
  4815. begin
  4816. At:=PEditorAction(Inherited At(Idx));
  4817. end;
  4818. function CreateFindDialog: PDialog;
  4819. var R,R1,R2: TRect;
  4820. D: PDialog;
  4821. IL1: PInputLine;
  4822. Control : PView;
  4823. CB1: PCheckBoxes;
  4824. RB1,RB2,RB3: PRadioButtons;
  4825. begin
  4826. R.Assign(0,0,56,15);
  4827. New(D, Init(R, 'Find'));
  4828. with D^ do
  4829. begin
  4830. Options:=Options or ofCentered;
  4831. GetExtent(R); R.Grow(-3,-2);
  4832. R1.Copy(R); R1.B.X:=17; R1.B.Y:=R1.A.Y+1;
  4833. R2.Copy(R); R2.B.X:=R2.B.X-3;R2.A.X:=17; R2.B.Y:=R2.A.Y+1;
  4834. New(IL1, Init(R2, FindStrSize));
  4835. IL1^.Data^:=FindStr;
  4836. Insert(IL1);
  4837. Insert(New(PLabel, Init(R1, '~T~ext to find', IL1)));
  4838. R1.Assign(R2.B.X, R2.A.Y, R2.B.X+3, R2.B.Y);
  4839. Control := New(PHistory, Init(R1, IL1, TextFindId));
  4840. Insert(Control);
  4841. 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;
  4842. R2.Copy(R1); R2.Move(0,1); R2.B.Y:=R2.A.Y+2;
  4843. New(CB1, Init(R2,
  4844. NewSItem('~C~ase sensitive',
  4845. NewSItem('~W~hole words only',
  4846. nil))));
  4847. Insert(CB1);
  4848. Insert(New(PLabel, Init(R1, 'Options', CB1)));
  4849. 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;
  4850. R2.Copy(R1); R2.Move(0,1); R2.B.Y:=R2.A.Y+2;
  4851. New(RB1, Init(R2,
  4852. NewSItem('Forwar~d~',
  4853. NewSItem('~B~ackward',
  4854. nil))));
  4855. Insert(RB1);
  4856. Insert(New(PLabel, Init(R1, 'Direction', RB1)));
  4857. 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;
  4858. R2.Copy(R1); R2.Move(0,1); R2.B.Y:=R2.A.Y+2;
  4859. New(RB2, Init(R2,
  4860. NewSItem('~G~lobal',
  4861. NewSItem('~S~elected text',
  4862. nil))));
  4863. Insert(RB2);
  4864. Insert(New(PLabel, Init(R1, 'Scope', RB2)));
  4865. 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;
  4866. R2.Copy(R1); R2.Move(0,1); R2.B.Y:=R2.A.Y+2;
  4867. New(RB3, Init(R2,
  4868. NewSItem('~F~rom cursor',
  4869. NewSItem('~E~ntire scope',
  4870. nil))));
  4871. Insert(RB3);
  4872. Insert(New(PLabel, Init(R1, 'Origin', RB3)));
  4873. GetExtent(R); R.Grow(-13,-1); R.A.Y:=R.B.Y-2; R.B.X:=R.A.X+10;
  4874. Insert(New(PButton, Init(R, 'O~K', cmOK, bfDefault)));
  4875. R.Move(19,0);
  4876. Insert(New(PButton, Init(R, 'Cancel', cmCancel, bfNormal)));
  4877. end;
  4878. IL1^.Select;
  4879. CreateFindDialog := D;
  4880. end;
  4881. function CreateReplaceDialog: PDialog;
  4882. var R,R1,R2: TRect;
  4883. D: PDialog;
  4884. Control : PView;
  4885. IL1,IL2: PInputLine;
  4886. CB1: PCheckBoxes;
  4887. RB1,RB2,RB3: PRadioButtons;
  4888. begin
  4889. R.Assign(0,0,56,18);
  4890. New(D, Init(R, 'Replace'));
  4891. with D^ do
  4892. begin
  4893. Options:=Options or ofCentered;
  4894. GetExtent(R); R.Grow(-3,-2);
  4895. R1.Copy(R); R1.B.X:=17; R1.B.Y:=R1.A.Y+1;
  4896. R2.Copy(R); R2.B.X:=R2.B.X-3;R2.A.X:=17; R2.B.Y:=R2.A.Y+1;
  4897. New(IL1, Init(R2, FindStrSize));
  4898. IL1^.Data^:=FindStr;
  4899. Insert(IL1);
  4900. Insert(New(PLabel, Init(R1, '~T~ext to find', IL1)));
  4901. R1.Assign(R2.B.X, R2.A.Y, R2.B.X+3, R2.B.Y);
  4902. Control := New(PHistory, Init(R1, IL1, TextFindId));
  4903. Insert(Control);
  4904. R1.Copy(R); R1.Move(0,2); R1.B.X:=17; R1.B.Y:=R1.A.Y+1;
  4905. R2.Copy(R); R2.Move(0,2);R2.B.X:=R2.B.X-3;
  4906. R2.A.X:=17; R2.B.Y:=R2.A.Y+1;
  4907. New(IL2, Init(R2, FindStrSize));
  4908. IL2^.Data^:=ReplaceStr;
  4909. Insert(IL2);
  4910. Insert(New(PLabel, Init(R1, ' ~N~ew text', IL2)));
  4911. R1.Assign(R2.B.X, R2.A.Y, R2.B.X+3, R2.B.Y);
  4912. Control := New(PHistory, Init(R1, IL2, TextReplaceId));
  4913. Insert(Control);
  4914. 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;
  4915. R2.Copy(R1); R2.Move(0,1); R2.B.Y:=R2.A.Y+3;
  4916. New(CB1, Init(R2,
  4917. NewSItem('~C~ase sensitive',
  4918. NewSItem('~W~hole words only',
  4919. NewSItem('~P~rompt on replace',
  4920. nil)))));
  4921. Insert(CB1);
  4922. Insert(New(PLabel, Init(R1, 'Options', CB1)));
  4923. 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;
  4924. R2.Copy(R1); R2.Move(0,1); R2.B.Y:=R2.A.Y+2;
  4925. New(RB1, Init(R2,
  4926. NewSItem('Forwar~d~',
  4927. NewSItem('~B~ackward',
  4928. nil))));
  4929. Insert(RB1);
  4930. Insert(New(PLabel, Init(R1, 'Direction', RB1)));
  4931. 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;
  4932. R2.Copy(R1); R2.Move(0,1); R2.B.Y:=R2.A.Y+2;
  4933. New(RB2, Init(R2,
  4934. NewSItem('~G~lobal',
  4935. NewSItem('~S~elected text',
  4936. nil))));
  4937. Insert(RB2);
  4938. Insert(New(PLabel, Init(R1, 'Scope', RB2)));
  4939. 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;
  4940. R2.Copy(R1); R2.Move(0,1); R2.B.Y:=R2.A.Y+2;
  4941. New(RB3, Init(R2,
  4942. NewSItem('~F~rom cursor',
  4943. NewSItem('~E~ntire scope',
  4944. nil))));
  4945. Insert(RB3);
  4946. Insert(New(PLabel, Init(R1, 'Origin', RB3)));
  4947. GetExtent(R); R.Grow(-13,-1); R.A.Y:=R.B.Y-2; R.B.X:=R.A.X+10; R.Move(-10,0);
  4948. Insert(New(PButton, Init(R, 'O~K~', cmOK, bfDefault)));
  4949. R.Move(11,0); R.B.X:=R.A.X+14;
  4950. Insert(New(PButton, Init(R, 'Change ~a~ll', cmYes, bfNormal)));
  4951. R.Move(15,0); R.B.X:=R.A.X+10;
  4952. Insert(New(PButton, Init(R, 'Cancel', cmCancel, bfNormal)));
  4953. end;
  4954. IL1^.Select;
  4955. CreateReplaceDialog := D;
  4956. end;
  4957. function CreateGotoLineDialog(Info: pointer): PDialog;
  4958. var D: PDialog;
  4959. R,R1,R2: TRect;
  4960. Control : PView;
  4961. IL: PInputLine;
  4962. begin
  4963. R.Assign(0,0,40,7);
  4964. New(D, Init(R, 'Goto line'));
  4965. with D^ do
  4966. begin
  4967. Options:=Options or ofCentered;
  4968. GetExtent(R); R.Grow(-3,-2); R.B.Y:=R.A.Y+1;
  4969. R1.Copy(R); R1.B.X:=27; R2.Copy(R);
  4970. R2.B.X:=R2.B.X-3;R2.A.X:=27;
  4971. New(IL, Init(R2,5));
  4972. with TGotoLineDialogRec(Info^) do
  4973. IL^.SetValidator(New(PRangeValidator, Init(1, Lines)));
  4974. Insert(IL);
  4975. Insert(New(PLabel, Init(R1, 'Enter new line ~n~umber', IL)));
  4976. R1.Assign(R2.B.X, R2.A.Y, R2.B.X+3, R2.B.Y);
  4977. Control := New(PHistory, Init(R1, IL, GotoId));
  4978. Insert(Control);
  4979. GetExtent(R); R.Grow(-8,-1); R.A.Y:=R.B.Y-2; R.B.X:=R.A.X+10;
  4980. Insert(New(PButton, Init(R, 'O~K', cmOK, bfDefault)));
  4981. R.Move(15,0);
  4982. Insert(New(PButton, Init(R, 'Cancel', cmCancel, bfNormal)));
  4983. end;
  4984. IL^.Select;
  4985. CreateGotoLineDialog:=D;
  4986. end;
  4987. function StdEditorDialog(Dialog: Integer; Info: Pointer): Word;
  4988. var
  4989. R: TRect;
  4990. T: TPoint;
  4991. Re: word;
  4992. Name: string;
  4993. DriveNumber : byte;
  4994. StoreDir,StoreDir2 : DirStr;
  4995. Title,DefExt: string;
  4996. AskOW: boolean;
  4997. begin
  4998. case Dialog of
  4999. edOutOfMemory:
  5000. StdEditorDialog := MessageBox('Not enough memory for this operation.',
  5001. nil, mfInsertInApp+ mfError + mfOkButton);
  5002. edReadError:
  5003. StdEditorDialog := MessageBox('Error reading file %s.',
  5004. @Info, mfInsertInApp+ mfError + mfOkButton);
  5005. edWriteError:
  5006. StdEditorDialog := MessageBox('Error writing file %s.',
  5007. @Info, mfInsertInApp+ mfError + mfOkButton);
  5008. edSaveError:
  5009. StdEditorDialog := MessageBox('Error saving file %s.',
  5010. @Info, mfInsertInApp+ mfError + mfOkButton);
  5011. edCreateError:
  5012. StdEditorDialog := MessageBox('Error creating file %s.',
  5013. @Info, mfInsertInApp+ mfError + mfOkButton);
  5014. edSaveModify:
  5015. StdEditorDialog := MessageBox('%s has been modified. Save?',
  5016. @Info, mfInsertInApp+ mfInformation + mfYesNoCancel);
  5017. edSaveUntitled:
  5018. StdEditorDialog := MessageBox('Save untitled file?',
  5019. nil, mfInsertInApp+ mfInformation + mfYesNoCancel);
  5020. edChangedOnloading:
  5021. StdEditorDialog := MessageBox(#3'File %s had too long lines'#13#3+
  5022. 'first such line is %d',
  5023. Info, mfInsertInApp+ mfOKButton + mfInformation);
  5024. edFileOnDiskChanged:
  5025. StdEditorDialog := MessageBox(#3'File %s '#13#3+
  5026. 'was modified by another program.'#13#3'Overwrite new version?',
  5027. @info, mfInsertInApp+ mfInformation + mfYesNoCancel);
  5028. edSaveAs,edWriteBlock,edReadBlock:
  5029. begin
  5030. Name:=PString(Info)^;
  5031. GetDir(0,StoreDir);
  5032. DriveNumber:=0;
  5033. if (Length(FileDir)>1) and (FileDir[2]=':') then
  5034. begin
  5035. { does not assume that lowercase are greater then uppercase ! }
  5036. if (FileDir[1]>='a') and (FileDir[1]>='z') then
  5037. DriveNumber:=Ord(FileDir[1])-ord('a')+1
  5038. else
  5039. DriveNumber:=Ord(FileDir[1])-ord('A')+1;
  5040. GetDir(DriveNumber,StoreDir2);
  5041. {$ifndef FPC}
  5042. ChDir(Copy(FileDir,1,2));
  5043. { this sets InOutRes in win32 PM }
  5044. { is this bad? What about an EatIO? Gabor }
  5045. {$endif not FPC}
  5046. end;
  5047. if FileDir<>'' then
  5048. ChDir(TrimEndSlash(FileDir));
  5049. case Dialog of
  5050. edSaveAs :
  5051. begin
  5052. Title:='Save File As';
  5053. DefExt:='*'+DefaultSaveExt;
  5054. end;
  5055. edWriteBlock :
  5056. begin
  5057. Title:='Write Block to File';
  5058. DefExt:='';
  5059. end;
  5060. edReadBlock :
  5061. begin
  5062. Title:='Read Block from File';
  5063. DefExt:='';
  5064. end;
  5065. else begin Title:='???'; DefExt:=''; end;
  5066. end;
  5067. Re:=Application^.ExecuteDialog(New(PFileDialog, Init(DefExt,
  5068. Title, '~N~ame', fdOkButton, FileId)), @Name);
  5069. case Dialog of
  5070. edSaveAs : AskOW:=(Name<>PString(Info)^);
  5071. edWriteBlock : AskOW:=true;
  5072. edReadBlock : AskOW:=false;
  5073. else AskOW:=true;
  5074. end;
  5075. if (Re<>cmCancel) and AskOW then
  5076. begin
  5077. FileDir:=DirOf(FExpand(Name));
  5078. if ExistsFile(Name) then
  5079. if EditorDialog(edReplaceFile,@Name)<>cmYes then
  5080. Re:=cmCancel;
  5081. end;
  5082. if DriveNumber<>0 then
  5083. ChDir(StoreDir2);
  5084. {$ifndef FPC}
  5085. if (Length(StoreDir)>1) and (StoreDir[2]=':') then
  5086. ChDir(Copy(StoreDir,1,2));
  5087. {$endif not FPC}
  5088. if StoreDir<>'' then
  5089. ChDir(TrimEndSlash(StoreDir));
  5090. if Re<>cmCancel then
  5091. PString(Info)^:=Name;
  5092. StdEditorDialog := Re;
  5093. end;
  5094. edGotoLine:
  5095. StdEditorDialog :=
  5096. Application^.ExecuteDialog(CreateGotoLineDialog(Info), Info);
  5097. edFind:
  5098. StdEditorDialog :=
  5099. Application^.ExecuteDialog(CreateFindDialog, Info);
  5100. edSearchFailed:
  5101. StdEditorDialog := MessageBox('Search string not found.',
  5102. nil, mfInsertInApp+ mfError + mfOkButton);
  5103. edReplace:
  5104. StdEditorDialog :=
  5105. Application^.ExecuteDialog(CreateReplaceDialog, Info);
  5106. edReplacePrompt:
  5107. begin
  5108. { Avoid placing the dialog on the same line as the cursor }
  5109. R.Assign(0, 1, 40, 8);
  5110. R.Move((Desktop^.Size.X - R.B.X) div 2, 0);
  5111. Desktop^.MakeGlobal(R.B, T);
  5112. Inc(T.Y);
  5113. if PPoint(Info)^.Y <= T.Y then
  5114. R.Move(0, Desktop^.Size.Y - R.B.Y - 2);
  5115. StdEditorDialog := MessageBoxRect(R, 'Replace this occurence?',
  5116. nil, mfInsertInApp+ mfYesNoCancel + mfInformation);
  5117. end;
  5118. edReplaceFile :
  5119. StdEditorDialog :=
  5120. MessageBox('File %s already exists. Overwrite?',@Info,mfInsertInApp+mfConfirmation+
  5121. mfYesButton+mfNoButton);
  5122. end;
  5123. end;
  5124. procedure RegisterWEditor;
  5125. begin
  5126. {$ifndef NOOBJREG}
  5127. {$endif}
  5128. end;
  5129. END.
  5130. {
  5131. $Log$
  5132. Revision 1.86 2000-03-23 21:36:19 pierre
  5133. * get correct position in indicator again
  5134. Revision 1.85 2000/03/21 23:17:47 pierre
  5135. + Gabor patch to add support for multiple windows
  5136. of same file
  5137. weditor has been splitted into weditor and wcedit units
  5138. Revision 1.84 2000/03/20 19:19:44 pierre
  5139. * LFN support in streams
  5140. Revision 1.83 2000/03/14 13:38:03 pierre
  5141. * max number of line changed and warning added
  5142. Revision 1.82 2000/03/02 22:33:36 pierre
  5143. * Grep improoved
  5144. Revision 1.81 2000/02/09 12:56:54 pierre
  5145. * fix for DelChar past end of line
  5146. Revision 1.80 2000/02/07 12:11:15 pierre
  5147. Gabors changes
  5148. Revision 1.79 2000/02/05 14:50:59 florian
  5149. * applied fix from Gabor regarding the limited line length of the clipboard
  5150. Revision 1.78 2000/01/28 22:20:04 pierre
  5151. * Test_partial_syntax released
  5152. Revision 1.77 2000/01/27 22:30:38 florian
  5153. * start of FPU window
  5154. * current executed line color has a higher priority then a breakpoint now
  5155. Revision 1.76 2000/01/25 00:12:23 pierre
  5156. * fix for Backspace Undo
  5157. Revision 1.75 2000/01/14 15:36:42 pierre
  5158. + GetShortFileName used for tcodeeditor file opening
  5159. Revision 1.74 2000/01/10 23:20:04 pierre
  5160. * problem with Paste solved
  5161. Revision 1.73 2000/01/10 13:25:46 pierre
  5162. + first partial syntax test
  5163. Revision 1.72 2000/01/07 00:19:30 pierre
  5164. * forgot CommentLineType check to see if we need to update format
  5165. on next line
  5166. * some changes for TEST_PARTIAL_SYNTAX still does notwork :(
  5167. Revision 1.71 2000/01/06 17:47:26 pierre
  5168. * avoid to resyntax whole source in unnecessary cases
  5169. Revision 1.70 2000/01/05 17:35:50 pierre
  5170. + Warning box if a line is cut at reading of file
  5171. this is done to avoid loosing completely long lines
  5172. * several TAB related changes
  5173. in particular do not remove or recombine TABs in makefiles
  5174. * fixes for ^KR and ^KW (the was an extra LF at end of
  5175. written block of disk and an error for starting X position
  5176. in SaveAreaToStream)
  5177. Revision 1.69 2000/01/05 00:37:34 pierre
  5178. * ^KC fix
  5179. * better Tab handling
  5180. Revision 1.68 2000/01/04 12:33:08 pierre
  5181. * reinserted version 1.66 lost changes
  5182. + CtrlT Undo works now !
  5183. Revision 1.67 2000/01/03 11:38:35 michael
  5184. Changes from Gabor
  5185. Revision 1.65 1999/12/08 16:02:46 pierre
  5186. * fix for bugs 746,748 and 750
  5187. Revision 1.64 1999/12/01 17:25:00 pierre
  5188. + check if file on disk was changed since load before overwriting
  5189. Revision 1.63 1999/11/22 17:34:08 pierre
  5190. * fix for form bug 634
  5191. Revision 1.62 1999/11/18 13:42:06 pierre
  5192. * Some more Undo stuff
  5193. Revision 1.61 1999/11/10 00:45:30 pierre
  5194. + groupd action started, not yet working
  5195. Revision 1.60 1999/11/05 13:49:13 pierre
  5196. * WinPaste depends on avalaible Clipboard data
  5197. Revision 1.59 1999/11/03 09:39:23 peter
  5198. * fixed uppercase filenames
  5199. * savetostream did twice a -1 on the linecount, so the lastline of a
  5200. file wasn't saved correctly
  5201. Revision 1.58 1999/10/28 15:14:22 pierre
  5202. * get it to compile with debug conditional
  5203. Revision 1.56 1999/10/27 13:32:58 pierre
  5204. * some more Undo Fixes
  5205. Revision 1.55 1999/10/27 10:46:19 pierre
  5206. * More Undo/Redo stuff
  5207. Revision 1.54 1999/10/25 16:49:05 pierre
  5208. + Undo/Redo by Visa Harvey (great thanks) inserted
  5209. (with some modifications)
  5210. Moves work correctly
  5211. Text insertion/deletion are still buggy !
  5212. * LinePosToCharIndex and reverse function changed to get more
  5213. sensible results, dependant code adapted
  5214. * several bug fixes
  5215. Revision 1.53 1999/10/14 10:21:48 pierre
  5216. * more tabs related problems fiwes
  5217. Revision 1.52 1999/10/12 23:35:18 pierre
  5218. + DelStart and SelectWord implemented
  5219. * AddChar(tab) now reacts correctly if efAutoIndent is set
  5220. Revision 1.51 1999/10/08 15:24:50 pierre
  5221. * InsertFrom bug (end of line wasdiscarded)
  5222. Revision 1.50 1999/09/28 23:44:13 pierre
  5223. * text insertion in middle of line was buggy
  5224. Revision 1.49 1999/09/23 16:33:30 pierre
  5225. * ^B^A now prints out the ascii 1 char
  5226. * In SearchReplace Several occurence of a pattern in the same line
  5227. should now be found correctly
  5228. Revision 1.48 1999/09/22 16:16:26 pierre
  5229. + added HistLists for several dialogs
  5230. Revision 1.47 1999/09/21 17:08:59 pierre
  5231. + Windows clipboard for win32
  5232. Revision 1.46 1999/09/13 16:24:44 peter
  5233. + clock
  5234. * backspace unident like tp7
  5235. Revision 1.45 1999/09/09 12:05:33 pierre
  5236. + Copy/Paste to Windows Clipboard
  5237. + efLeaveTrailingSpaces added to editor flags
  5238. (if not set then spaces at the end of a line are
  5239. removed on writing the file)
  5240. Revision 1.44 1999/08/27 15:07:44 pierre
  5241. + cmResetDebuggerRow
  5242. Revision 1.43 1999/08/24 22:04:35 pierre
  5243. + TCodeEditor.SetDebuggerRow
  5244. works like SetHighlightRow but is only disposed by a SetDebuggerRow(-1)
  5245. so the current stop point in debugging is not lost if
  5246. we move the cursor
  5247. Revision 1.42 1999/08/22 22:20:30 pierre
  5248. * selection extension bug removed, via oldEvent pointer in TCodeEditor.HandleEvent
  5249. Revision 1.41 1999/08/16 18:25:28 peter
  5250. * Adjusting the selection when the editor didn't contain any line.
  5251. * Reserved word recognition redesigned, but this didn't affect the overall
  5252. syntax highlight speed remarkably (at least not on my Amd-K6/350).
  5253. The syntax scanner loop is a bit slow but the main problem is the
  5254. recognition of special symbols. Switching off symbol processing boosts
  5255. the performance up to ca. 200%...
  5256. * The editor didn't allow copying (for ex to clipboard) of a single character
  5257. * 'File|Save as' caused permanently run-time error 3. Not any more now...
  5258. * Compiler Messages window (actually the whole desktop) did not act on any
  5259. keypress when compilation failed and thus the window remained visible
  5260. + Message windows are now closed upon pressing Esc
  5261. + At 'Run' the IDE checks whether any sources are modified, and recompiles
  5262. only when neccessary
  5263. + BlockRead and BlockWrite (Ctrl+K+R/W) implemented in TCodeEditor
  5264. + LineSelect (Ctrl+K+L) implemented
  5265. * The IDE had problems closing help windows before saving the desktop
  5266. Revision 1.40 1999/08/03 20:22:42 peter
  5267. + TTab acts now on Ctrl+Tab and Ctrl+Shift+Tab...
  5268. + Desktop saving should work now
  5269. - History saved
  5270. - Clipboard content saved
  5271. - Desktop saved
  5272. - Symbol info saved
  5273. * syntax-highlight bug fixed, which compared special keywords case sensitive
  5274. (for ex. 'asm' caused asm-highlighting, while 'ASM' didn't)
  5275. * with 'whole words only' set, the editor didn't found occourences of the
  5276. searched text, if the text appeared previously in the same line, but didn't
  5277. satisfied the 'whole-word' condition
  5278. * ^QB jumped to (SelStart.X,SelEnd.X) instead of (SelStart.X,SelStart.Y)
  5279. (ie. the beginning of the selection)
  5280. * when started typing in a new line, but not at the start (X=0) of it,
  5281. the editor inserted the text one character more to left as it should...
  5282. * TCodeEditor.HideSelection (Ctrl-K+H) didn't update the screen
  5283. * Shift shouldn't cause so much trouble in TCodeEditor now...
  5284. * Syntax highlight had problems recognizing a special symbol if it was
  5285. prefixed by another symbol character in the source text
  5286. * Auto-save also occours at Dos shell, Tool execution, etc. now...
  5287. Revision 1.39 1999/07/28 23:11:26 peter
  5288. * fixes from gabor
  5289. Revision 1.38 1999/07/12 13:14:24 pierre
  5290. * LineEnd bug corrected, now goes end of text even if selected
  5291. + Until Return for debugger
  5292. + Code for Quit inside GDB Window
  5293. Revision 1.37 1999/06/29 22:50:16 peter
  5294. * more fixes from gabor
  5295. Revision 1.36 1999/06/29 08:51:34 pierre
  5296. * lockflag problems fixed
  5297. Revision 1.35 1999/06/28 19:32:32 peter
  5298. * fixes from gabor
  5299. Revision 1.34 1999/06/28 15:58:07 pierre
  5300. * ShiftDel problem solved
  5301. Revision 1.33 1999/06/25 00:31:51 pierre
  5302. + FileDir remembers the last directory for Open and Save
  5303. Revision 1.32 1999/06/21 23:36:12 pierre
  5304. * Size for Cluster is word (TP compatibility)
  5305. Revision 1.31 1999/05/22 13:44:35 peter
  5306. * fixed couple of bugs
  5307. Revision 1.30 1999/04/15 08:58:10 peter
  5308. * syntax highlight fixes
  5309. * browser updates
  5310. Revision 1.29 1999/04/07 21:55:59 peter
  5311. + object support for browser
  5312. * html help fixes
  5313. * more desktop saving things
  5314. * NODEBUG directive to exclude debugger
  5315. Revision 1.28 1999/03/23 15:11:39 peter
  5316. * desktop saving things
  5317. * vesa mode
  5318. * preferences dialog
  5319. Revision 1.27 1999/03/08 14:58:17 peter
  5320. + prompt with dialogs for tools
  5321. Revision 1.26 1999/03/07 22:58:57 pierre
  5322. * FindRec needs longint for CheckBoxes
  5323. Revision 1.25 1999/03/05 17:39:39 pierre
  5324. * Actions item freeing
  5325. Revision 1.24 1999/03/03 16:45:07 pierre
  5326. * Actions were not dispose in TCodeEditor.Done
  5327. Revision 1.23 1999/03/01 15:42:10 peter
  5328. + Added dummy entries for functions not yet implemented
  5329. * MenuBar didn't update itself automatically on command-set changes
  5330. * Fixed Debugging/Profiling options dialog
  5331. * TCodeEditor converts spaces to tabs at save only if efUseTabChars is set
  5332. * efBackSpaceUnindents works correctly
  5333. + 'Messages' window implemented
  5334. + Added '$CAP MSG()' and '$CAP EDIT' to available tool-macros
  5335. + Added TP message-filter support (for ex. you can call GREP thru
  5336. GREP2MSG and view the result in the messages window - just like in TP)
  5337. * A 'var' was missing from the param-list of THelpFacility.TopicSearch,
  5338. so topic search didn't work...
  5339. * In FPHELP.PAS there were still context-variables defined as word instead
  5340. of THelpCtx
  5341. * StdStatusKeys() was missing from the statusdef for help windows
  5342. + Topic-title for index-table can be specified when adding a HTML-files
  5343. Revision 1.22 1999/02/22 02:15:25 peter
  5344. + default extension for save in the editor
  5345. + Separate Text to Find for the grep dialog
  5346. * fixed redir crash with tp7
  5347. Revision 1.21 1999/02/20 15:18:33 peter
  5348. + ctrl-c capture with confirm dialog
  5349. + ascii table in the tools menu
  5350. + heapviewer
  5351. * empty file fixed
  5352. * fixed callback routines in fpdebug to have far for tp7
  5353. Revision 1.20 1999/02/18 17:27:57 pierre
  5354. * find/replace dialogs need packed records !!
  5355. Revision 1.19 1999/02/18 13:44:36 peter
  5356. * search fixed
  5357. + backward search
  5358. * help fixes
  5359. * browser updates
  5360. Revision 1.18 1999/02/15 15:12:25 pierre
  5361. + TLine remembers Comment type
  5362. Revision 1.17 1999/02/15 09:32:58 pierre
  5363. * single line comment // fix : comments intermix still wrong !!
  5364. Revision 1.16 1999/02/11 19:07:26 pierre
  5365. * GDBWindow redesigned :
  5366. normal editor apart from
  5367. that any kbEnter will send the line (for begin to cursor)
  5368. to GDB command !
  5369. GDBWindow opened in Debugger Menu
  5370. still buggy :
  5371. -echo should not be present if at end of text
  5372. -GDBWindow becomes First after each step (I don't know why !)
  5373. Revision 1.15 1999/02/09 09:29:59 pierre
  5374. * avoid invisible characters in CombineColors
  5375. Revision 1.14 1999/02/05 13:51:45 peter
  5376. * unit name of FPSwitches -> FPSwitch which is easier to use
  5377. * some fixes for tp7 compiling
  5378. Revision 1.13 1999/02/05 13:22:43 pierre
  5379. * bug that caused crash for empty files
  5380. Revision 1.12 1999/02/05 12:04:56 pierre
  5381. + 'loose' centering for debugger
  5382. Revision 1.11 1999/02/04 17:19:26 peter
  5383. * linux fixes
  5384. Revision 1.10 1999/02/04 10:13:00 pierre
  5385. + GetCurrentWord (used in Find/Replace)
  5386. + DefUseTabsPattern (pattern forcing tabs to be kept)
  5387. used for all makefiles !!
  5388. Revision 1.9 1999/01/29 10:34:33 peter
  5389. + needobjdir,needlibdir
  5390. Revision 1.8 1999/01/21 11:54:31 peter
  5391. + tools menu
  5392. + speedsearch in symbolbrowser
  5393. * working run command
  5394. Revision 1.7 1999/01/14 21:41:17 peter
  5395. * use * as modified indicator
  5396. * fixed syntax highlighting
  5397. Revision 1.6 1999/01/12 14:29:44 peter
  5398. + Implemented still missing 'switch' entries in Options menu
  5399. + Pressing Ctrl-B sets ASCII mode in editor, after which keypresses (even
  5400. ones with ASCII < 32 ; entered with Alt+<###>) are interpreted always as
  5401. ASCII chars and inserted directly in the text.
  5402. + Added symbol browser
  5403. * splitted fp.pas to fpide.pas
  5404. Revision 1.5 1999/01/07 15:02:40 peter
  5405. * better tab support
  5406. Revision 1.4 1999/01/04 11:49:55 peter
  5407. * 'Use tab characters' now works correctly
  5408. + Syntax highlight now acts on File|Save As...
  5409. + Added a new class to syntax highlight: 'hex numbers'.
  5410. * There was something very wrong with the palette managment. Now fixed.
  5411. + Added output directory (-FE<xxx>) support to 'Directories' dialog...
  5412. * Fixed some possible bugs in Running/Compiling, and the compilation/run
  5413. process revised
  5414. Revision 1.2 1998/12/28 15:47:55 peter
  5415. + Added user screen support, display & window
  5416. + Implemented Editor,Mouse Options dialog
  5417. + Added location of .INI and .CFG file
  5418. + Option (INI) file managment implemented (see bottom of Options Menu)
  5419. + Switches updated
  5420. + Run program
  5421. Revision 1.4 1998/12/27 12:01:23 gabor
  5422. * efXXXX constants revised for BP compatibility
  5423. * fixed column and row highlighting (needs to rewrite default palette in the INI)
  5424. Revision 1.3 1998/12/22 10:39:54 peter
  5425. + options are now written/read
  5426. + find and replace routines
  5427. }