weditor.pas 199 KB

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