weditor.pas 198 KB

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