cperl-mode.el 322 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980
  1. ;;; cperl-mode.el --- Perl code editing commands for Emacs
  2. ;; Copyright (C) 1985-1987, 1991-2012 Free Software Foundation, Inc.
  3. ;; Author: Ilya Zakharevich
  4. ;; Bob Olson
  5. ;; Maintainer: Ilya Zakharevich <ilyaz@cpan.org>
  6. ;; Keywords: languages, Perl
  7. ;; This file is part of GNU Emacs.
  8. ;; GNU Emacs is free software: you can redistribute it and/or modify
  9. ;; it under the terms of the GNU General Public License as published by
  10. ;; the Free Software Foundation, either version 3 of the License, or
  11. ;; (at your option) any later version.
  12. ;; GNU Emacs is distributed in the hope that it will be useful,
  13. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. ;; GNU General Public License for more details.
  16. ;; You should have received a copy of the GNU General Public License
  17. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  18. ;;; Corrections made by Ilya Zakharevich ilyaz@cpan.org
  19. ;;; Commentary:
  20. ;; You can either fine-tune the bells and whistles of this mode or
  21. ;; bulk enable them by putting
  22. ;; (setq cperl-hairy t)
  23. ;; in your .emacs file. (Emacs rulers do not consider it politically
  24. ;; correct to make whistles enabled by default.)
  25. ;; DO NOT FORGET to read micro-docs (available from `Perl' menu) <<<<<<
  26. ;; or as help on variables `cperl-tips', `cperl-problems', <<<<<<
  27. ;; `cperl-praise', `cperl-speed'. <<<<<<
  28. ;; The mode information (on C-h m) provides some customization help.
  29. ;; If you use font-lock feature of this mode, it is advisable to use
  30. ;; either lazy-lock-mode or fast-lock-mode. I prefer lazy-lock.
  31. ;; Faces used now: three faces for first-class and second-class keywords
  32. ;; and control flow words, one for each: comments, string, labels,
  33. ;; functions definitions and packages, arrays, hashes, and variable
  34. ;; definitions. If you do not see all these faces, your font-lock does
  35. ;; not define them, so you need to define them manually.
  36. ;; This mode supports font-lock, imenu and mode-compile. In the
  37. ;; hairy version font-lock is on, but you should activate imenu
  38. ;; yourself (note that mode-compile is not standard yet). Well, you
  39. ;; can use imenu from keyboard anyway (M-x imenu), but it is better
  40. ;; to bind it like that:
  41. ;; (define-key global-map [M-S-down-mouse-3] 'imenu)
  42. ;;; Font lock bugs as of v4.32:
  43. ;; The following kinds of Perl code erroneously start strings:
  44. ;; \$` \$' \$"
  45. ;; $opt::s $opt_s $opt{s} (s => ...) /\s+.../
  46. ;; likewise with m, tr, y, q, qX instead of s
  47. ;;; Code:
  48. (defvar vc-rcs-header)
  49. (defvar vc-sccs-header)
  50. (eval-when-compile
  51. (condition-case nil
  52. (require 'custom)
  53. (error nil))
  54. (condition-case nil
  55. (require 'man)
  56. (error nil))
  57. (defvar cperl-can-font-lock
  58. (or (featurep 'xemacs)
  59. (and (boundp 'emacs-major-version)
  60. (or window-system
  61. (> emacs-major-version 20)))))
  62. (if cperl-can-font-lock
  63. (require 'font-lock))
  64. (defvar msb-menu-cond)
  65. (defvar gud-perldb-history)
  66. (defvar font-lock-background-mode) ; not in Emacs
  67. (defvar font-lock-display-type) ; ditto
  68. (defvar paren-backwards-message) ; Not in newer XEmacs?
  69. (or (fboundp 'defgroup)
  70. (defmacro defgroup (name val doc &rest arr)
  71. nil))
  72. (or (fboundp 'custom-declare-variable)
  73. (defmacro defcustom (name val doc &rest arr)
  74. `(defvar ,name ,val ,doc)))
  75. (or (and (fboundp 'custom-declare-variable)
  76. (string< "19.31" emacs-version)) ; Checked with 19.30: defface does not work
  77. (defmacro defface (&rest arr)
  78. nil))
  79. ;; Avoid warning (tmp definitions)
  80. (or (fboundp 'x-color-defined-p)
  81. (defmacro x-color-defined-p (col)
  82. (cond ((fboundp 'color-defined-p) `(color-defined-p ,col))
  83. ;; XEmacs >= 19.12
  84. ((fboundp 'valid-color-name-p) `(valid-color-name-p ,col))
  85. ;; XEmacs 19.11
  86. ((fboundp 'x-valid-color-name-p) `(x-valid-color-name-p ,col))
  87. (t '(error "Cannot implement color-defined-p")))))
  88. (defmacro cperl-is-face (arg) ; Takes quoted arg
  89. (cond ((fboundp 'find-face)
  90. `(find-face ,arg))
  91. (;;(and (fboundp 'face-list)
  92. ;; (face-list))
  93. (fboundp 'face-list)
  94. `(member ,arg (and (fboundp 'face-list)
  95. (face-list))))
  96. (t
  97. `(boundp ,arg))))
  98. (defmacro cperl-make-face (arg descr) ; Takes unquoted arg
  99. (cond ((fboundp 'make-face)
  100. `(make-face (quote ,arg)))
  101. (t
  102. `(defvar ,arg (quote ,arg) ,descr))))
  103. (defmacro cperl-force-face (arg descr) ; Takes unquoted arg
  104. `(progn
  105. (or (cperl-is-face (quote ,arg))
  106. (cperl-make-face ,arg ,descr))
  107. (or (boundp (quote ,arg)) ; We use unquoted variants too
  108. (defvar ,arg (quote ,arg) ,descr))))
  109. (if (featurep 'xemacs)
  110. (defmacro cperl-etags-snarf-tag (file line)
  111. `(progn
  112. (beginning-of-line 2)
  113. (list ,file ,line)))
  114. (defmacro cperl-etags-snarf-tag (file line)
  115. `(etags-snarf-tag)))
  116. (if (featurep 'xemacs)
  117. (defmacro cperl-etags-goto-tag-location (elt)
  118. ;;(progn
  119. ;; (switch-to-buffer (get-file-buffer (elt ,elt 0)))
  120. ;; (set-buffer (get-file-buffer (elt ,elt 0)))
  121. ;; Probably will not work due to some save-excursion???
  122. ;; Or save-file-position?
  123. ;; (message "Did I get to line %s?" (elt ,elt 1))
  124. `(goto-line (string-to-int (elt ,elt 1))))
  125. ;;)
  126. (defmacro cperl-etags-goto-tag-location (elt)
  127. `(etags-goto-tag-location ,elt))))
  128. (defvar cperl-can-font-lock
  129. (or (featurep 'xemacs)
  130. (and (boundp 'emacs-major-version)
  131. (or window-system
  132. (> emacs-major-version 20)))))
  133. (defun cperl-choose-color (&rest list)
  134. (let (answer)
  135. (while list
  136. (or answer
  137. (if (or (x-color-defined-p (car list))
  138. (null (cdr list)))
  139. (setq answer (car list))))
  140. (setq list (cdr list)))
  141. answer))
  142. (defgroup cperl nil
  143. "Major mode for editing Perl code."
  144. :prefix "cperl-"
  145. :group 'languages
  146. :version "20.3")
  147. (defgroup cperl-indentation-details nil
  148. "Indentation."
  149. :prefix "cperl-"
  150. :group 'cperl)
  151. (defgroup cperl-affected-by-hairy nil
  152. "Variables affected by `cperl-hairy'."
  153. :prefix "cperl-"
  154. :group 'cperl)
  155. (defgroup cperl-autoinsert-details nil
  156. "Auto-insert tuneup."
  157. :prefix "cperl-"
  158. :group 'cperl)
  159. (defgroup cperl-faces nil
  160. "Fontification colors."
  161. :link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces)
  162. :prefix "cperl-"
  163. :group 'cperl)
  164. (defgroup cperl-speed nil
  165. "Speed vs. validity tuneup."
  166. :prefix "cperl-"
  167. :group 'cperl)
  168. (defgroup cperl-help-system nil
  169. "Help system tuneup."
  170. :prefix "cperl-"
  171. :group 'cperl)
  172. (defcustom cperl-extra-newline-before-brace nil
  173. "*Non-nil means that if, elsif, while, until, else, for, foreach
  174. and do constructs look like:
  175. if ()
  176. {
  177. }
  178. instead of:
  179. if () {
  180. }"
  181. :type 'boolean
  182. :group 'cperl-autoinsert-details)
  183. (defcustom cperl-extra-newline-before-brace-multiline
  184. cperl-extra-newline-before-brace
  185. "*Non-nil means the same as `cperl-extra-newline-before-brace', but
  186. for constructs with multiline if/unless/while/until/for/foreach condition."
  187. :type 'boolean
  188. :group 'cperl-autoinsert-details)
  189. (defcustom cperl-indent-level 2
  190. "*Indentation of CPerl statements with respect to containing block."
  191. :type 'integer
  192. :group 'cperl-indentation-details)
  193. ;; Is is not unusual to put both things like perl-indent-level and
  194. ;; cperl-indent-level in the local variable section of a file. If only
  195. ;; one of perl-mode and cperl-mode is in use, a warning will be issued
  196. ;; about the variable. Autoload these here, so that no warning is
  197. ;; issued when using either perl-mode or cperl-mode.
  198. ;;;###autoload(put 'cperl-indent-level 'safe-local-variable 'integerp)
  199. ;;;###autoload(put 'cperl-brace-offset 'safe-local-variable 'integerp)
  200. ;;;###autoload(put 'cperl-continued-brace-offset 'safe-local-variable 'integerp)
  201. ;;;###autoload(put 'cperl-label-offset 'safe-local-variable 'integerp)
  202. ;;;###autoload(put 'cperl-continued-statement-offset 'safe-local-variable 'integerp)
  203. ;;;###autoload(put 'cperl-extra-newline-before-brace 'safe-local-variable 'booleanp)
  204. ;;;###autoload(put 'cperl-merge-trailing-else 'safe-local-variable 'booleanp)
  205. (defcustom cperl-lineup-step nil
  206. "*`cperl-lineup' will always lineup at multiple of this number.
  207. If nil, the value of `cperl-indent-level' will be used."
  208. :type '(choice (const nil) integer)
  209. :group 'cperl-indentation-details)
  210. (defcustom cperl-brace-imaginary-offset 0
  211. "*Imagined indentation of a Perl open brace that actually follows a statement.
  212. An open brace following other text is treated as if it were this far
  213. to the right of the start of its line."
  214. :type 'integer
  215. :group 'cperl-indentation-details)
  216. (defcustom cperl-brace-offset 0
  217. "*Extra indentation for braces, compared with other text in same context."
  218. :type 'integer
  219. :group 'cperl-indentation-details)
  220. (defcustom cperl-label-offset -2
  221. "*Offset of CPerl label lines relative to usual indentation."
  222. :type 'integer
  223. :group 'cperl-indentation-details)
  224. (defcustom cperl-min-label-indent 1
  225. "*Minimal offset of CPerl label lines."
  226. :type 'integer
  227. :group 'cperl-indentation-details)
  228. (defcustom cperl-continued-statement-offset 2
  229. "*Extra indent for lines not starting new statements."
  230. :type 'integer
  231. :group 'cperl-indentation-details)
  232. (defcustom cperl-continued-brace-offset 0
  233. "*Extra indent for substatements that start with open-braces.
  234. This is in addition to cperl-continued-statement-offset."
  235. :type 'integer
  236. :group 'cperl-indentation-details)
  237. (defcustom cperl-close-paren-offset -1
  238. "*Extra indent for substatements that start with close-parenthesis."
  239. :type 'integer
  240. :group 'cperl-indentation-details)
  241. (defcustom cperl-indent-wrt-brace t
  242. "*Non-nil means indent statements in if/etc block relative brace, not if/etc.
  243. Versions 5.2 ... 5.20 behaved as if this were `nil'."
  244. :type 'boolean
  245. :group 'cperl-indentation-details)
  246. (defcustom cperl-auto-newline nil
  247. "*Non-nil means automatically newline before and after braces,
  248. and after colons and semicolons, inserted in CPerl code. The following
  249. \\[cperl-electric-backspace] will remove the inserted whitespace.
  250. Insertion after colons requires both this variable and
  251. `cperl-auto-newline-after-colon' set."
  252. :type 'boolean
  253. :group 'cperl-autoinsert-details)
  254. (defcustom cperl-autoindent-on-semi nil
  255. "*Non-nil means automatically indent after insertion of (semi)colon.
  256. Active if `cperl-auto-newline' is false."
  257. :type 'boolean
  258. :group 'cperl-autoinsert-details)
  259. (defcustom cperl-auto-newline-after-colon nil
  260. "*Non-nil means automatically newline even after colons.
  261. Subject to `cperl-auto-newline' setting."
  262. :type 'boolean
  263. :group 'cperl-autoinsert-details)
  264. (defcustom cperl-tab-always-indent t
  265. "*Non-nil means TAB in CPerl mode should always reindent the current line,
  266. regardless of where in the line point is when the TAB command is used."
  267. :type 'boolean
  268. :group 'cperl-indentation-details)
  269. (defcustom cperl-font-lock nil
  270. "*Non-nil (and non-null) means CPerl buffers will use `font-lock-mode'.
  271. Can be overwritten by `cperl-hairy' if nil."
  272. :type '(choice (const null) boolean)
  273. :group 'cperl-affected-by-hairy)
  274. (defcustom cperl-electric-lbrace-space nil
  275. "*Non-nil (and non-null) means { after $ should be preceded by ` '.
  276. Can be overwritten by `cperl-hairy' if nil."
  277. :type '(choice (const null) boolean)
  278. :group 'cperl-affected-by-hairy)
  279. (defcustom cperl-electric-parens-string "({[]})<"
  280. "*String of parentheses that should be electric in CPerl.
  281. Closing ones are electric only if the region is highlighted."
  282. :type 'string
  283. :group 'cperl-affected-by-hairy)
  284. (defcustom cperl-electric-parens nil
  285. "*Non-nil (and non-null) means parentheses should be electric in CPerl.
  286. Can be overwritten by `cperl-hairy' if nil."
  287. :type '(choice (const null) boolean)
  288. :group 'cperl-affected-by-hairy)
  289. (defvar zmacs-regions) ; Avoid warning
  290. (defcustom cperl-electric-parens-mark
  291. (and window-system
  292. (or (and (boundp 'transient-mark-mode) ; For Emacs
  293. transient-mark-mode)
  294. (and (boundp 'zmacs-regions) ; For XEmacs
  295. zmacs-regions)))
  296. "*Not-nil means that electric parens look for active mark.
  297. Default is yes if there is visual feedback on mark."
  298. :type 'boolean
  299. :group 'cperl-autoinsert-details)
  300. (defcustom cperl-electric-linefeed nil
  301. "*If true, LFD should be hairy in CPerl, otherwise C-c LFD is hairy.
  302. In any case these two mean plain and hairy linefeeds together.
  303. Can be overwritten by `cperl-hairy' if nil."
  304. :type '(choice (const null) boolean)
  305. :group 'cperl-affected-by-hairy)
  306. (defcustom cperl-electric-keywords nil
  307. "*Not-nil (and non-null) means keywords are electric in CPerl.
  308. Can be overwritten by `cperl-hairy' if nil.
  309. Uses `abbrev-mode' to do the expansion. If you want to use your
  310. own abbrevs in cperl-mode, but do not want keywords to be
  311. electric, you must redefine `cperl-mode-abbrev-table': do
  312. \\[edit-abbrevs], search for `cperl-mode-abbrev-table', and, in
  313. that paragraph, delete the words that appear at the ends of lines and
  314. that begin with \"cperl-electric\".
  315. "
  316. :type '(choice (const null) boolean)
  317. :group 'cperl-affected-by-hairy)
  318. (defcustom cperl-electric-backspace-untabify t
  319. "*Not-nil means electric-backspace will untabify in CPerl."
  320. :type 'boolean
  321. :group 'cperl-autoinsert-details)
  322. (defcustom cperl-hairy nil
  323. "*Not-nil means most of the bells and whistles are enabled in CPerl.
  324. Affects: `cperl-font-lock', `cperl-electric-lbrace-space',
  325. `cperl-electric-parens', `cperl-electric-linefeed', `cperl-electric-keywords',
  326. `cperl-info-on-command-no-prompt', `cperl-clobber-lisp-bindings',
  327. `cperl-lazy-help-time'."
  328. :type 'boolean
  329. :group 'cperl-affected-by-hairy)
  330. (defcustom cperl-comment-column 32
  331. "*Column to put comments in CPerl (use \\[cperl-indent] to lineup with code)."
  332. :type 'integer
  333. :group 'cperl-indentation-details)
  334. (defcustom cperl-indent-comment-at-column-0 nil
  335. "*Non-nil means that comment started at column 0 should be indentable."
  336. :type 'boolean
  337. :group 'cperl-indentation-details)
  338. (defcustom cperl-vc-sccs-header '("($sccs) = ('%W\%' =~ /(\\d+(\\.\\d+)+)/) ;")
  339. "*Special version of `vc-sccs-header' that is used in CPerl mode buffers."
  340. :type '(repeat string)
  341. :group 'cperl)
  342. (defcustom cperl-vc-rcs-header '("($rcs) = (' $Id\$ ' =~ /(\\d+(\\.\\d+)+)/);")
  343. "*Special version of `vc-rcs-header' that is used in CPerl mode buffers."
  344. :type '(repeat string)
  345. :group 'cperl)
  346. ;; This became obsolete...
  347. (defvar cperl-vc-header-alist nil)
  348. (make-obsolete-variable
  349. 'cperl-vc-header-alist
  350. "use cperl-vc-rcs-header or cperl-vc-sccs-header instead."
  351. "22.1")
  352. (defcustom cperl-clobber-mode-lists
  353. (not
  354. (and
  355. (boundp 'interpreter-mode-alist)
  356. (assoc "miniperl" interpreter-mode-alist)
  357. (assoc "\\.\\([pP][Llm]\\|al\\)$" auto-mode-alist)))
  358. "*Whether to install us into `interpreter-' and `extension' mode lists."
  359. :type 'boolean
  360. :group 'cperl)
  361. (defcustom cperl-info-on-command-no-prompt nil
  362. "*Not-nil (and non-null) means not to prompt on C-h f.
  363. The opposite behavior is always available if prefixed with C-c.
  364. Can be overwritten by `cperl-hairy' if nil."
  365. :type '(choice (const null) boolean)
  366. :group 'cperl-affected-by-hairy)
  367. (defcustom cperl-clobber-lisp-bindings nil
  368. "*Not-nil (and non-null) means not overwrite C-h f.
  369. The function is available on \\[cperl-info-on-command], \\[cperl-get-help].
  370. Can be overwritten by `cperl-hairy' if nil."
  371. :type '(choice (const null) boolean)
  372. :group 'cperl-affected-by-hairy)
  373. (defcustom cperl-lazy-help-time nil
  374. "*Not-nil (and non-null) means to show lazy help after given idle time.
  375. Can be overwritten by `cperl-hairy' to be 5 sec if nil."
  376. :type '(choice (const null) (const nil) integer)
  377. :group 'cperl-affected-by-hairy)
  378. (defcustom cperl-pod-face 'font-lock-comment-face
  379. "*Face for POD highlighting."
  380. :type 'face
  381. :group 'cperl-faces)
  382. (defcustom cperl-pod-head-face 'font-lock-variable-name-face
  383. "*Face for POD highlighting.
  384. Font for POD headers."
  385. :type 'face
  386. :group 'cperl-faces)
  387. (defcustom cperl-here-face 'font-lock-string-face
  388. "*Face for here-docs highlighting."
  389. :type 'face
  390. :group 'cperl-faces)
  391. ;;; Some double-evaluation happened with font-locks... Needed with 21.2...
  392. (defvar cperl-singly-quote-face (featurep 'xemacs))
  393. (defcustom cperl-invalid-face 'underline
  394. "*Face for highlighting trailing whitespace."
  395. :type 'face
  396. :version "21.1"
  397. :group 'cperl-faces)
  398. (defcustom cperl-pod-here-fontify '(featurep 'font-lock)
  399. "*Not-nil after evaluation means to highlight POD and here-docs sections."
  400. :type 'boolean
  401. :group 'cperl-faces)
  402. (defcustom cperl-fontify-m-as-s t
  403. "*Not-nil means highlight 1arg regular expressions operators same as 2arg."
  404. :type 'boolean
  405. :group 'cperl-faces)
  406. (defcustom cperl-highlight-variables-indiscriminately nil
  407. "*Non-nil means perform additional highlighting on variables.
  408. Currently only changes how scalar variables are highlighted.
  409. Note that that variable is only read at initialization time for
  410. the variable `cperl-font-lock-keywords-2', so changing it after you've
  411. entered CPerl mode the first time will have no effect."
  412. :type 'boolean
  413. :group 'cperl)
  414. (defcustom cperl-pod-here-scan t
  415. "*Not-nil means look for POD and here-docs sections during startup.
  416. You can always make lookup from menu or using \\[cperl-find-pods-heres]."
  417. :type 'boolean
  418. :group 'cperl-speed)
  419. (defcustom cperl-regexp-scan t
  420. "*Not-nil means make marking of regular expression more thorough.
  421. Effective only with `cperl-pod-here-scan'."
  422. :type 'boolean
  423. :group 'cperl-speed)
  424. (defcustom cperl-hook-after-change t
  425. "*Not-nil means install hook to know which regions of buffer are changed.
  426. May significantly speed up delayed fontification. Changes take effect
  427. after reload."
  428. :type 'boolean
  429. :group 'cperl-speed)
  430. (defcustom cperl-imenu-addback nil
  431. "*Not-nil means add backreferences to generated `imenu's.
  432. May require patched `imenu' and `imenu-go'. Obsolete."
  433. :type 'boolean
  434. :group 'cperl-help-system)
  435. (defcustom cperl-max-help-size 66
  436. "*Non-nil means shrink-wrapping of info-buffer allowed up to these percents."
  437. :type '(choice integer (const nil))
  438. :group 'cperl-help-system)
  439. (defcustom cperl-shrink-wrap-info-frame t
  440. "*Non-nil means shrink-wrapping of info-buffer-frame allowed."
  441. :type 'boolean
  442. :group 'cperl-help-system)
  443. (defcustom cperl-info-page "perl"
  444. "*Name of the info page containing perl docs.
  445. Older version of this page was called `perl5', newer `perl'."
  446. :type 'string
  447. :group 'cperl-help-system)
  448. (defcustom cperl-use-syntax-table-text-property
  449. (boundp 'parse-sexp-lookup-properties)
  450. "*Non-nil means CPerl sets up and uses `syntax-table' text property."
  451. :type 'boolean
  452. :group 'cperl-speed)
  453. (defcustom cperl-use-syntax-table-text-property-for-tags
  454. cperl-use-syntax-table-text-property
  455. "*Non-nil means: set up and use `syntax-table' text property generating TAGS."
  456. :type 'boolean
  457. :group 'cperl-speed)
  458. (defcustom cperl-scan-files-regexp "\\.\\([pP][Llm]\\|xs\\)$"
  459. "*Regexp to match files to scan when generating TAGS."
  460. :type 'regexp
  461. :group 'cperl)
  462. (defcustom cperl-noscan-files-regexp
  463. "/\\(\\.\\.?\\|SCCS\\|RCS\\|CVS\\|blib\\)$"
  464. "*Regexp to match files/dirs to skip when generating TAGS."
  465. :type 'regexp
  466. :group 'cperl)
  467. (defcustom cperl-regexp-indent-step nil
  468. "*Indentation used when beautifying regexps.
  469. If nil, the value of `cperl-indent-level' will be used."
  470. :type '(choice integer (const nil))
  471. :group 'cperl-indentation-details)
  472. (defcustom cperl-indent-left-aligned-comments t
  473. "*Non-nil means that the comment starting in leftmost column should indent."
  474. :type 'boolean
  475. :group 'cperl-indentation-details)
  476. (defcustom cperl-under-as-char nil
  477. "*Non-nil means that the _ (underline) should be treated as word char."
  478. :type 'boolean
  479. :group 'cperl)
  480. (defcustom cperl-extra-perl-args ""
  481. "*Extra arguments to use when starting Perl.
  482. Currently used with `cperl-check-syntax' only."
  483. :type 'string
  484. :group 'cperl)
  485. (defcustom cperl-message-electric-keyword t
  486. "*Non-nil means that the `cperl-electric-keyword' prints a help message."
  487. :type 'boolean
  488. :group 'cperl-help-system)
  489. (defcustom cperl-indent-region-fix-constructs 1
  490. "*Amount of space to insert between `}' and `else' or `elsif'
  491. in `cperl-indent-region'. Set to nil to leave as is. Values other
  492. than 1 and nil will probably not work."
  493. :type '(choice (const nil) (const 1))
  494. :group 'cperl-indentation-details)
  495. (defcustom cperl-break-one-line-blocks-when-indent t
  496. "*Non-nil means that one-line if/unless/while/until/for/foreach BLOCKs
  497. need to be reformatted into multiline ones when indenting a region."
  498. :type 'boolean
  499. :group 'cperl-indentation-details)
  500. (defcustom cperl-fix-hanging-brace-when-indent t
  501. "*Non-nil means that BLOCK-end `}' may be put on a separate line
  502. when indenting a region.
  503. Braces followed by else/elsif/while/until are excepted."
  504. :type 'boolean
  505. :group 'cperl-indentation-details)
  506. (defcustom cperl-merge-trailing-else t
  507. "*Non-nil means that BLOCK-end `}' followed by else/elsif/continue
  508. may be merged to be on the same line when indenting a region."
  509. :type 'boolean
  510. :group 'cperl-indentation-details)
  511. (defcustom cperl-indent-parens-as-block nil
  512. "*Non-nil means that non-block ()-, {}- and []-groups are indented as blocks,
  513. but for trailing \",\" inside the group, which won't increase indentation.
  514. One should tune up `cperl-close-paren-offset' as well."
  515. :type 'boolean
  516. :group 'cperl-indentation-details)
  517. (defcustom cperl-syntaxify-by-font-lock
  518. (and cperl-can-font-lock
  519. (boundp 'parse-sexp-lookup-properties))
  520. "*Non-nil means that CPerl uses the `font-lock' routines for syntaxification."
  521. :type '(choice (const message) boolean)
  522. :group 'cperl-speed)
  523. (defcustom cperl-syntaxify-unwind
  524. t
  525. "*Non-nil means that CPerl unwinds to a start of a long construction
  526. when syntaxifying a chunk of buffer."
  527. :type 'boolean
  528. :group 'cperl-speed)
  529. (defcustom cperl-syntaxify-for-menu
  530. t
  531. "*Non-nil means that CPerl syntaxifies up to the point before showing menu.
  532. This way enabling/disabling of menu items is more correct."
  533. :type 'boolean
  534. :group 'cperl-speed)
  535. (defcustom cperl-ps-print-face-properties
  536. '((font-lock-keyword-face nil nil bold shadow)
  537. (font-lock-variable-name-face nil nil bold)
  538. (font-lock-function-name-face nil nil bold italic box)
  539. (font-lock-constant-face nil "LightGray" bold)
  540. (cperl-array-face nil "LightGray" bold underline)
  541. (cperl-hash-face nil "LightGray" bold italic underline)
  542. (font-lock-comment-face nil "LightGray" italic)
  543. (font-lock-string-face nil nil italic underline)
  544. (cperl-nonoverridable-face nil nil italic underline)
  545. (font-lock-type-face nil nil underline)
  546. (font-lock-warning-face nil "LightGray" bold italic box)
  547. (underline nil "LightGray" strikeout))
  548. "List given as an argument to `ps-extend-face-list' in `cperl-ps-print'."
  549. :type '(repeat (cons symbol
  550. (cons (choice (const nil) string)
  551. (cons (choice (const nil) string)
  552. (repeat symbol)))))
  553. :group 'cperl-faces)
  554. (defvar cperl-dark-background
  555. (cperl-choose-color "navy" "os2blue" "darkgreen"))
  556. (defvar cperl-dark-foreground
  557. (cperl-choose-color "orchid1" "orange"))
  558. (defface cperl-nonoverridable-face
  559. `((((class grayscale) (background light))
  560. (:background "Gray90" :slant italic :underline t))
  561. (((class grayscale) (background dark))
  562. (:foreground "Gray80" :slant italic :underline t :weight bold))
  563. (((class color) (background light))
  564. (:foreground "chartreuse3"))
  565. (((class color) (background dark))
  566. (:foreground ,cperl-dark-foreground))
  567. (t (:weight bold :underline t)))
  568. "Font Lock mode face used non-overridable keywords and modifiers of regexps."
  569. :group 'cperl-faces)
  570. (defface cperl-array-face
  571. `((((class grayscale) (background light))
  572. (:background "Gray90" :weight bold))
  573. (((class grayscale) (background dark))
  574. (:foreground "Gray80" :weight bold))
  575. (((class color) (background light))
  576. (:foreground "Blue" :background "lightyellow2" :weight bold))
  577. (((class color) (background dark))
  578. (:foreground "yellow" :background ,cperl-dark-background :weight bold))
  579. (t (:weight bold)))
  580. "Font Lock mode face used to highlight array names."
  581. :group 'cperl-faces)
  582. (defface cperl-hash-face
  583. `((((class grayscale) (background light))
  584. (:background "Gray90" :weight bold :slant italic))
  585. (((class grayscale) (background dark))
  586. (:foreground "Gray80" :weight bold :slant italic))
  587. (((class color) (background light))
  588. (:foreground "Red" :background "lightyellow2" :weight bold :slant italic))
  589. (((class color) (background dark))
  590. (:foreground "Red" :background ,cperl-dark-background :weight bold :slant italic))
  591. (t (:weight bold :slant italic)))
  592. "Font Lock mode face used to highlight hash names."
  593. :group 'cperl-faces)
  594. ;;; Short extra-docs.
  595. (defvar cperl-tips 'please-ignore-this-line
  596. "Get maybe newer version of this package from
  597. http://ilyaz.org/software/emacs
  598. Subdirectory `cperl-mode' may contain yet newer development releases and/or
  599. patches to related files.
  600. For best results apply to an older Emacs the patches from
  601. ftp://ftp.math.ohio-state.edu/pub/users/ilya/cperl-mode/patches
  602. \(this upgrades syntax-parsing abilities of Emacsen v19.34 and
  603. v20.2 up to the level of Emacs v20.3 - a must for a good Perl
  604. mode.) As of beginning of 2003, XEmacs may provide a similar ability.
  605. Get support packages choose-color.el (or font-lock-extra.el before
  606. 19.30), imenu-go.el from the same place. \(Look for other files there
  607. too... ;-). Get a patch for imenu.el in 19.29. Note that for 19.30 and
  608. later you should use choose-color.el *instead* of font-lock-extra.el
  609. \(and you will not get smart highlighting in C :-().
  610. Note that to enable Compile choices in the menu you need to install
  611. mode-compile.el.
  612. If your Emacs does not default to `cperl-mode' on Perl files, and you
  613. want it to: put the following into your .emacs file:
  614. (defalias 'perl-mode 'cperl-mode)
  615. Get perl5-info from
  616. $CPAN/doc/manual/info/perl5-old/perl5-info.tar.gz
  617. Also, one can generate a newer documentation running `pod2texi' converter
  618. $CPAN/doc/manual/info/perl5/pod2texi-0.1.tar.gz
  619. If you use imenu-go, run imenu on perl5-info buffer (you can do it
  620. from Perl menu). If many files are related, generate TAGS files from
  621. Tools/Tags submenu in Perl menu.
  622. If some class structure is too complicated, use Tools/Hierarchy-view
  623. from Perl menu, or hierarchic view of imenu. The second one uses the
  624. current buffer only, the first one requires generation of TAGS from
  625. Perl/Tools/Tags menu beforehand.
  626. Run Perl/Tools/Insert-spaces-if-needed to fix your lazy typing.
  627. Switch auto-help on/off with Perl/Tools/Auto-help.
  628. Though with contemporary Emaxen CPerl mode should maintain the correct
  629. parsing of Perl even when editing, sometimes it may be lost. Fix this by
  630. \\[normal-mode]
  631. In cases of more severe confusion sometimes it is helpful to do
  632. \\[load-library] cperl-mode RET
  633. \\[normal-mode]
  634. Before reporting (non-)problems look in the problem section of online
  635. micro-docs on what I know about CPerl problems.")
  636. (defvar cperl-problems 'please-ignore-this-line
  637. "Description of problems in CPerl mode.
  638. Some faces will not be shown on some versions of Emacs unless you
  639. install choose-color.el, available from
  640. http://ilyaz.org/software/emacs
  641. `fill-paragraph' on a comment may leave the point behind the
  642. paragraph. It also triggers a bug in some versions of Emacs (CPerl tries
  643. to detect it and bulk out).
  644. See documentation of a variable `cperl-problems-old-emaxen' for the
  645. problems which disappear if you upgrade Emacs to a reasonably new
  646. version (20.3 for Emacs, and those of 2004 for XEmacs).")
  647. (defvar cperl-problems-old-emaxen 'please-ignore-this-line
  648. "Description of problems in CPerl mode specific for older Emacs versions.
  649. Emacs had a _very_ restricted syntax parsing engine until version
  650. 20.1. Most problems below are corrected starting from this version of
  651. Emacs, and all of them should be fixed in version 20.3. (Or apply
  652. patches to Emacs 19.33/34 - see tips.) XEmacs was very backward in
  653. this respect (until 2003).
  654. Note that even with newer Emacsen in some very rare cases the details
  655. of interaction of `font-lock' and syntaxification may be not cleaned
  656. up yet. You may get slightly different colors basing on the order of
  657. fontification and syntaxification. Say, the initial faces is correct,
  658. but editing the buffer breaks this.
  659. Even with older Emacsen CPerl mode tries to corrects some Emacs
  660. misunderstandings, however, for efficiency reasons the degree of
  661. correction is different for different operations. The partially
  662. corrected problems are: POD sections, here-documents, regexps. The
  663. operations are: highlighting, indentation, electric keywords, electric
  664. braces.
  665. This may be confusing, since the regexp s#//#/#\; may be highlighted
  666. as a comment, but it will be recognized as a regexp by the indentation
  667. code. Or the opposite case, when a POD section is highlighted, but
  668. may break the indentation of the following code (though indentation
  669. should work if the balance of delimiters is not broken by POD).
  670. The main trick (to make $ a \"backslash\") makes constructions like
  671. ${aaa} look like unbalanced braces. The only trick I can think of is
  672. to insert it as $ {aaa} (valid in perl5, not in perl4).
  673. Similar problems arise in regexps, when /(\\s|$)/ should be rewritten
  674. as /($|\\s)/. Note that such a transposition is not always possible.
  675. The solution is to upgrade your Emacs or patch an older one. Note
  676. that Emacs 20.2 has some bugs related to `syntax-table' text
  677. properties. Patches are available on the main CPerl download site,
  678. and on CPAN.
  679. If these bugs cannot be fixed on your machine (say, you have an inferior
  680. environment and cannot recompile), you may still disable all the fancy stuff
  681. via `cperl-use-syntax-table-text-property'.")
  682. (defvar cperl-praise 'please-ignore-this-line
  683. "Advantages of CPerl mode.
  684. 0) It uses the newest `syntax-table' property ;-);
  685. 1) It does 99% of Perl syntax correct (as opposed to 80-90% in Perl
  686. mode - but the latter number may have improved too in last years) even
  687. with old Emaxen which do not support `syntax-table' property.
  688. When using `syntax-table' property for syntax assist hints, it should
  689. handle 99.995% of lines correct - or somesuch. It automatically
  690. updates syntax assist hints when you edit your script.
  691. 2) It is generally believed to be \"the most user-friendly Emacs
  692. package\" whatever it may mean (I doubt that the people who say similar
  693. things tried _all_ the rest of Emacs ;-), but this was not a lonely
  694. voice);
  695. 3) Everything is customizable, one-by-one or in a big sweep;
  696. 4) It has many easily-accessible \"tools\":
  697. a) Can run program, check syntax, start debugger;
  698. b) Can lineup vertically \"middles\" of rows, like `=' in
  699. a = b;
  700. cc = d;
  701. c) Can insert spaces where this improves readability (in one
  702. interactive sweep over the buffer);
  703. d) Has support for imenu, including:
  704. 1) Separate unordered list of \"interesting places\";
  705. 2) Separate TOC of POD sections;
  706. 3) Separate list of packages;
  707. 4) Hierarchical view of methods in (sub)packages;
  708. 5) and functions (by the full name - with package);
  709. e) Has an interface to INFO docs for Perl; The interface is
  710. very flexible, including shrink-wrapping of
  711. documentation buffer/frame;
  712. f) Has a builtin list of one-line explanations for perl constructs.
  713. g) Can show these explanations if you stay long enough at the
  714. corresponding place (or on demand);
  715. h) Has an enhanced fontification (using 3 or 4 additional faces
  716. comparing to font-lock - basically, different
  717. namespaces in Perl have different colors);
  718. i) Can construct TAGS basing on its knowledge of Perl syntax,
  719. the standard menu has 6 different way to generate
  720. TAGS (if \"by directory\", .xs files - with C-language
  721. bindings - are included in the scan);
  722. j) Can build a hierarchical view of classes (via imenu) basing
  723. on generated TAGS file;
  724. k) Has electric parentheses, electric newlines, uses Abbrev
  725. for electric logical constructs
  726. while () {}
  727. with different styles of expansion (context sensitive
  728. to be not so bothering). Electric parentheses behave
  729. \"as they should\" in a presence of a visible region.
  730. l) Changes msb.el \"on the fly\" to insert a group \"Perl files\";
  731. m) Can convert from
  732. if (A) { B }
  733. to
  734. B if A;
  735. n) Highlights (by user-choice) either 3-delimiters constructs
  736. (such as tr/a/b/), or regular expressions and `y/tr';
  737. o) Highlights trailing whitespace;
  738. p) Is able to manipulate Perl Regular Expressions to ease
  739. conversion to a more readable form.
  740. q) Can ispell POD sections and HERE-DOCs.
  741. r) Understands comments and character classes inside regular
  742. expressions; can find matching () and [] in a regular expression.
  743. s) Allows indentation of //x-style regular expressions;
  744. t) Highlights different symbols in regular expressions according
  745. to their function; much less problems with backslashitis;
  746. u) Allows to find regular expressions which contain interpolated parts.
  747. 5) The indentation engine was very smart, but most of tricks may be
  748. not needed anymore with the support for `syntax-table' property. Has
  749. progress indicator for indentation (with `imenu' loaded).
  750. 6) Indent-region improves inline-comments as well; also corrects
  751. whitespace *inside* the conditional/loop constructs.
  752. 7) Fill-paragraph correctly handles multi-line comments;
  753. 8) Can switch to different indentation styles by one command, and restore
  754. the settings present before the switch.
  755. 9) When doing indentation of control constructs, may correct
  756. line-breaks/spacing between elements of the construct.
  757. 10) Uses a linear-time algorithm for indentation of regions (on Emaxen with
  758. capable syntax engines).
  759. 11) Syntax-highlight, indentation, sexp-recognition inside regular expressions.
  760. ")
  761. (defvar cperl-speed 'please-ignore-this-line
  762. "This is an incomplete compendium of what is available in other parts
  763. of CPerl documentation. (Please inform me if I skept anything.)
  764. There is a perception that CPerl is slower than alternatives. This part
  765. of documentation is designed to overcome this misconception.
  766. *By default* CPerl tries to enable the most comfortable settings.
  767. From most points of view, correctly working package is infinitely more
  768. comfortable than a non-correctly working one, thus by default CPerl
  769. prefers correctness over speed. Below is the guide how to change
  770. settings if your preferences are different.
  771. A) Speed of loading the file. When loading file, CPerl may perform a
  772. scan which indicates places which cannot be parsed by primitive Emacs
  773. syntax-parsing routines, and marks them up so that either
  774. A1) CPerl may work around these deficiencies (for big chunks, mostly
  775. PODs and HERE-documents), or
  776. A2) On capable Emaxen CPerl will use improved syntax-handling
  777. which reads mark-up hints directly.
  778. The scan in case A2 is much more comprehensive, thus may be slower.
  779. User can disable syntax-engine-helping scan of A2 by setting
  780. `cperl-use-syntax-table-text-property'
  781. variable to nil (if it is set to t).
  782. One can disable the scan altogether (both A1 and A2) by setting
  783. `cperl-pod-here-scan'
  784. to nil.
  785. B) Speed of editing operations.
  786. One can add a (minor) speedup to editing operations by setting
  787. `cperl-use-syntax-table-text-property'
  788. variable to nil (if it is set to t). This will disable
  789. syntax-engine-helping scan, thus will make many more Perl
  790. constructs be wrongly recognized by CPerl, thus may lead to
  791. wrongly matched parentheses, wrong indentation, etc.
  792. One can unset `cperl-syntaxify-unwind'. This might speed up editing
  793. of, say, long POD sections.")
  794. (defvar cperl-tips-faces 'please-ignore-this-line
  795. "CPerl mode uses following faces for highlighting:
  796. `cperl-array-face' Array names
  797. `cperl-hash-face' Hash names
  798. `font-lock-comment-face' Comments, PODs and whatever is considered
  799. syntactically to be not code
  800. `font-lock-constant-face' HERE-doc delimiters, labels, delimiters of
  801. 2-arg operators s/y/tr/ or of RExen,
  802. `font-lock-warning-face' Special-cased m// and s//foo/,
  803. `font-lock-function-name-face' _ as a target of a file tests, file tests,
  804. subroutine names at the moment of definition
  805. (except those conflicting with Perl operators),
  806. package names (when recognized), format names
  807. `font-lock-keyword-face' Control flow switch constructs, declarators
  808. `cperl-nonoverridable-face' Non-overridable keywords, modifiers of RExen
  809. `font-lock-string-face' Strings, qw() constructs, RExen, POD sections,
  810. literal parts and the terminator of formats
  811. and whatever is syntactically considered
  812. as string literals
  813. `font-lock-type-face' Overridable keywords
  814. `font-lock-variable-name-face' Variable declarations, indirect array and
  815. hash names, POD headers/item names
  816. `cperl-invalid-face' Trailing whitespace
  817. Note that in several situations the highlighting tries to inform about
  818. possible confusion, such as different colors for function names in
  819. declarations depending on what they (do not) override, or special cases
  820. m// and s/// which do not do what one would expect them to do.
  821. Help with best setup of these faces for printout requested (for each of
  822. the faces: please specify bold, italic, underline, shadow and box.)
  823. In regular expressions (including character classes):
  824. `font-lock-string-face' \"Normal\" stuff and non-0-length constructs
  825. `font-lock-constant-face': Delimiters
  826. `font-lock-warning-face' Special-cased m// and s//foo/,
  827. Mismatched closing delimiters, parens
  828. we couldn't match, misplaced quantifiers,
  829. unrecognized escape sequences
  830. `cperl-nonoverridable-face' Modifiers, as gism in m/REx/gism
  831. `font-lock-type-face' escape sequences with arguments (\\x \\23 \\p \\N)
  832. and others match-a-char escape sequences
  833. `font-lock-keyword-face' Capturing parens, and |
  834. `font-lock-function-name-face' Special symbols: $ ^ . [ ] [^ ] (?{ }) (??{ })
  835. \"Range -\" in character classes
  836. `font-lock-builtin-face' \"Remaining\" 0-length constructs, multipliers
  837. ?+*{}, not-capturing parens, leading
  838. backslashes of escape sequences
  839. `font-lock-variable-name-face' Interpolated constructs, embedded code,
  840. POSIX classes (inside charclasses)
  841. `font-lock-comment-face' Embedded comments
  842. ")
  843. ;;; Portability stuff:
  844. (defmacro cperl-define-key (emacs-key definition &optional xemacs-key)
  845. `(define-key cperl-mode-map
  846. ,(if xemacs-key
  847. `(if (featurep 'xemacs) ,xemacs-key ,emacs-key)
  848. emacs-key)
  849. ,definition))
  850. (defvar cperl-del-back-ch
  851. (car (append (where-is-internal 'delete-backward-char)
  852. (where-is-internal 'backward-delete-char-untabify)))
  853. "Character generated by key bound to `delete-backward-char'.")
  854. (and (vectorp cperl-del-back-ch) (= (length cperl-del-back-ch) 1)
  855. (setq cperl-del-back-ch (aref cperl-del-back-ch 0)))
  856. (defun cperl-mark-active () (mark)) ; Avoid undefined warning
  857. (if (featurep 'xemacs)
  858. (progn
  859. ;; "Active regions" are on: use region only if active
  860. ;; "Active regions" are off: use region unconditionally
  861. (defun cperl-use-region-p ()
  862. (if zmacs-regions (mark) t)))
  863. (defun cperl-use-region-p ()
  864. (if transient-mark-mode mark-active t))
  865. (defun cperl-mark-active () mark-active))
  866. (defsubst cperl-enable-font-lock ()
  867. cperl-can-font-lock)
  868. (defun cperl-putback-char (c) ; Emacs 19
  869. (set 'unread-command-events (list c))) ; Avoid undefined warning
  870. (if (featurep 'xemacs)
  871. (defun cperl-putback-char (c) ; XEmacs >= 19.12
  872. (setq unread-command-events (list (eval '(character-to-event c))))))
  873. (or (fboundp 'uncomment-region)
  874. (defun uncomment-region (beg end)
  875. (interactive "r")
  876. (comment-region beg end -1)))
  877. (defvar cperl-do-not-fontify
  878. (if (string< emacs-version "19.30")
  879. 'fontified
  880. 'lazy-lock)
  881. "Text property which inhibits refontification.")
  882. (defsubst cperl-put-do-not-fontify (from to &optional post)
  883. ;; If POST, do not do it with postponed fontification
  884. (if (and post cperl-syntaxify-by-font-lock)
  885. nil
  886. (put-text-property (max (point-min) (1- from))
  887. to cperl-do-not-fontify t)))
  888. (defcustom cperl-mode-hook nil
  889. "Hook run by CPerl mode."
  890. :type 'hook
  891. :group 'cperl)
  892. (defvar cperl-syntax-state nil)
  893. (defvar cperl-syntax-done-to nil)
  894. (defvar cperl-emacs-can-parse (> (length (save-excursion
  895. (parse-partial-sexp (point) (point)))) 9))
  896. ;; Make customization possible "in reverse"
  897. (defsubst cperl-val (symbol &optional default hairy)
  898. (cond
  899. ((eq (symbol-value symbol) 'null) default)
  900. (cperl-hairy (or hairy t))
  901. (t (symbol-value symbol))))
  902. (defun cperl-make-indent (column &optional minimum keep)
  903. "Makes indent of the current line the requested amount.
  904. Unless KEEP, removes the old indentation. Works around a bug in ancient
  905. versions of Emacs."
  906. (let ((prop (get-text-property (point) 'syntax-type)))
  907. (or keep
  908. (delete-horizontal-space))
  909. (indent-to column minimum)
  910. ;; In old versions (e.g., 19.33) `indent-to' would not inherit properties
  911. (and prop
  912. (> (current-column) 0)
  913. (save-excursion
  914. (beginning-of-line)
  915. (or (get-text-property (point) 'syntax-type)
  916. (and (looking-at "\\=[ \t]")
  917. (put-text-property (point) (match-end 0)
  918. 'syntax-type prop)))))))
  919. ;;; Probably it is too late to set these guys already, but it can help later:
  920. ;;;(and cperl-clobber-mode-lists
  921. ;;;(setq auto-mode-alist
  922. ;;; (append '(("\\.\\([pP][Llm]\\|al\\)$" . perl-mode)) auto-mode-alist ))
  923. ;;;(and (boundp 'interpreter-mode-alist)
  924. ;;; (setq interpreter-mode-alist (append interpreter-mode-alist
  925. ;;; '(("miniperl" . perl-mode))))))
  926. (eval-when-compile
  927. (mapc (lambda (p)
  928. (condition-case nil
  929. (require p)
  930. (error nil)))
  931. '(imenu easymenu etags timer man info))
  932. (if (fboundp 'ps-extend-face-list)
  933. (defmacro cperl-ps-extend-face-list (arg)
  934. `(ps-extend-face-list ,arg))
  935. (defmacro cperl-ps-extend-face-list (arg)
  936. `(error "This version of Emacs has no `ps-extend-face-list'")))
  937. ;; Calling `cperl-enable-font-lock' below doesn't compile on XEmacs,
  938. ;; macros instead of defsubsts don't work on Emacs, so we do the
  939. ;; expansion manually. Any other suggestions?
  940. (require 'cl))
  941. (defvar cperl-mode-abbrev-table nil
  942. "Abbrev table in use in CPerl mode buffers.")
  943. (add-hook 'edit-var-mode-alist '(perl-mode (regexp . "^cperl-")))
  944. (defvar cperl-mode-map () "Keymap used in CPerl mode.")
  945. (if cperl-mode-map nil
  946. (setq cperl-mode-map (make-sparse-keymap))
  947. (cperl-define-key "{" 'cperl-electric-lbrace)
  948. (cperl-define-key "[" 'cperl-electric-paren)
  949. (cperl-define-key "(" 'cperl-electric-paren)
  950. (cperl-define-key "<" 'cperl-electric-paren)
  951. (cperl-define-key "}" 'cperl-electric-brace)
  952. (cperl-define-key "]" 'cperl-electric-rparen)
  953. (cperl-define-key ")" 'cperl-electric-rparen)
  954. (cperl-define-key ";" 'cperl-electric-semi)
  955. (cperl-define-key ":" 'cperl-electric-terminator)
  956. (cperl-define-key "\C-j" 'newline-and-indent)
  957. (cperl-define-key "\C-c\C-j" 'cperl-linefeed)
  958. (cperl-define-key "\C-c\C-t" 'cperl-invert-if-unless)
  959. (cperl-define-key "\C-c\C-a" 'cperl-toggle-auto-newline)
  960. (cperl-define-key "\C-c\C-k" 'cperl-toggle-abbrev)
  961. (cperl-define-key "\C-c\C-w" 'cperl-toggle-construct-fix)
  962. (cperl-define-key "\C-c\C-f" 'auto-fill-mode)
  963. (cperl-define-key "\C-c\C-e" 'cperl-toggle-electric)
  964. (cperl-define-key "\C-c\C-b" 'cperl-find-bad-style)
  965. (cperl-define-key "\C-c\C-p" 'cperl-pod-spell)
  966. (cperl-define-key "\C-c\C-d" 'cperl-here-doc-spell)
  967. (cperl-define-key "\C-c\C-n" 'cperl-narrow-to-here-doc)
  968. (cperl-define-key "\C-c\C-v" 'cperl-next-interpolated-REx)
  969. (cperl-define-key "\C-c\C-x" 'cperl-next-interpolated-REx-0)
  970. (cperl-define-key "\C-c\C-y" 'cperl-next-interpolated-REx-1)
  971. (cperl-define-key "\C-c\C-ha" 'cperl-toggle-autohelp)
  972. (cperl-define-key "\C-c\C-hp" 'cperl-perldoc)
  973. (cperl-define-key "\C-c\C-hP" 'cperl-perldoc-at-point)
  974. (cperl-define-key "\e\C-q" 'cperl-indent-exp) ; Usually not bound
  975. (cperl-define-key [?\C-\M-\|] 'cperl-lineup
  976. [(control meta |)])
  977. ;;(cperl-define-key "\M-q" 'cperl-fill-paragraph)
  978. ;;(cperl-define-key "\e;" 'cperl-indent-for-comment)
  979. (cperl-define-key "\177" 'cperl-electric-backspace)
  980. (cperl-define-key "\t" 'cperl-indent-command)
  981. ;; don't clobber the backspace binding:
  982. (cperl-define-key "\C-c\C-hF" 'cperl-info-on-command
  983. [(control c) (control h) F])
  984. (if (cperl-val 'cperl-clobber-lisp-bindings)
  985. (progn
  986. (cperl-define-key "\C-hf"
  987. ;;(concat (char-to-string help-char) "f") ; does not work
  988. 'cperl-info-on-command
  989. [(control h) f])
  990. (cperl-define-key "\C-hv"
  991. ;;(concat (char-to-string help-char) "v") ; does not work
  992. 'cperl-get-help
  993. [(control h) v])
  994. (cperl-define-key "\C-c\C-hf"
  995. ;;(concat (char-to-string help-char) "f") ; does not work
  996. (key-binding "\C-hf")
  997. [(control c) (control h) f])
  998. (cperl-define-key "\C-c\C-hv"
  999. ;;(concat (char-to-string help-char) "v") ; does not work
  1000. (key-binding "\C-hv")
  1001. [(control c) (control h) v]))
  1002. (cperl-define-key "\C-c\C-hf" 'cperl-info-on-current-command
  1003. [(control c) (control h) f])
  1004. (cperl-define-key "\C-c\C-hv"
  1005. ;;(concat (char-to-string help-char) "v") ; does not work
  1006. 'cperl-get-help
  1007. [(control c) (control h) v]))
  1008. (if (and (featurep 'xemacs)
  1009. (<= emacs-minor-version 11) (<= emacs-major-version 19))
  1010. (progn
  1011. ;; substitute-key-definition is usefulness-deenhanced...
  1012. ;;;;;(cperl-define-key "\M-q" 'cperl-fill-paragraph)
  1013. (cperl-define-key "\e;" 'cperl-indent-for-comment)
  1014. (cperl-define-key "\e\C-\\" 'cperl-indent-region))
  1015. (or (boundp 'fill-paragraph-function)
  1016. (substitute-key-definition
  1017. 'fill-paragraph 'cperl-fill-paragraph
  1018. cperl-mode-map global-map))
  1019. (substitute-key-definition
  1020. 'indent-sexp 'cperl-indent-exp
  1021. cperl-mode-map global-map)
  1022. (substitute-key-definition
  1023. 'indent-region 'cperl-indent-region
  1024. cperl-mode-map global-map)
  1025. (substitute-key-definition
  1026. 'indent-for-comment 'cperl-indent-for-comment
  1027. cperl-mode-map global-map)))
  1028. (defvar cperl-menu)
  1029. (defvar cperl-lazy-installed)
  1030. (defvar cperl-old-style nil)
  1031. (condition-case nil
  1032. (progn
  1033. (require 'easymenu)
  1034. (easy-menu-define
  1035. cperl-menu cperl-mode-map "Menu for CPerl mode"
  1036. '("Perl"
  1037. ["Beginning of function" beginning-of-defun t]
  1038. ["End of function" end-of-defun t]
  1039. ["Mark function" mark-defun t]
  1040. ["Indent expression" cperl-indent-exp t]
  1041. ["Fill paragraph/comment" fill-paragraph t]
  1042. "----"
  1043. ["Line up a construction" cperl-lineup (cperl-use-region-p)]
  1044. ["Invert if/unless/while etc" cperl-invert-if-unless t]
  1045. ("Regexp"
  1046. ["Beautify" cperl-beautify-regexp
  1047. cperl-use-syntax-table-text-property]
  1048. ["Beautify one level deep" (cperl-beautify-regexp 1)
  1049. cperl-use-syntax-table-text-property]
  1050. ["Beautify a group" cperl-beautify-level
  1051. cperl-use-syntax-table-text-property]
  1052. ["Beautify a group one level deep" (cperl-beautify-level 1)
  1053. cperl-use-syntax-table-text-property]
  1054. ["Contract a group" cperl-contract-level
  1055. cperl-use-syntax-table-text-property]
  1056. ["Contract groups" cperl-contract-levels
  1057. cperl-use-syntax-table-text-property]
  1058. "----"
  1059. ["Find next interpolated" cperl-next-interpolated-REx
  1060. (next-single-property-change (point-min) 'REx-interpolated)]
  1061. ["Find next interpolated (no //o)"
  1062. cperl-next-interpolated-REx-0
  1063. (or (text-property-any (point-min) (point-max) 'REx-interpolated t)
  1064. (text-property-any (point-min) (point-max) 'REx-interpolated 1))]
  1065. ["Find next interpolated (neither //o nor whole-REx)"
  1066. cperl-next-interpolated-REx-1
  1067. (text-property-any (point-min) (point-max) 'REx-interpolated t)])
  1068. ["Insert spaces if needed to fix style" cperl-find-bad-style t]
  1069. ["Refresh \"hard\" constructions" cperl-find-pods-heres t]
  1070. "----"
  1071. ["Indent region" cperl-indent-region (cperl-use-region-p)]
  1072. ["Comment region" cperl-comment-region (cperl-use-region-p)]
  1073. ["Uncomment region" cperl-uncomment-region (cperl-use-region-p)]
  1074. "----"
  1075. ["Run" mode-compile (fboundp 'mode-compile)]
  1076. ["Kill" mode-compile-kill (and (fboundp 'mode-compile-kill)
  1077. (get-buffer "*compilation*"))]
  1078. ["Next error" next-error (get-buffer "*compilation*")]
  1079. ["Check syntax" cperl-check-syntax (fboundp 'mode-compile)]
  1080. "----"
  1081. ["Debugger" cperl-db t]
  1082. "----"
  1083. ("Tools"
  1084. ["Imenu" imenu (fboundp 'imenu)]
  1085. ["Imenu on Perl Info" cperl-imenu-on-info (featurep 'imenu)]
  1086. "----"
  1087. ["Ispell PODs" cperl-pod-spell
  1088. ;; Better not to update syntaxification here:
  1089. ;; debugging syntaxification can be broken by this???
  1090. (or
  1091. (get-text-property (point-min) 'in-pod)
  1092. (< (progn
  1093. (and cperl-syntaxify-for-menu
  1094. (cperl-update-syntaxification (point-max) (point-max)))
  1095. (next-single-property-change (point-min) 'in-pod nil (point-max)))
  1096. (point-max)))]
  1097. ["Ispell HERE-DOCs" cperl-here-doc-spell
  1098. (< (progn
  1099. (and cperl-syntaxify-for-menu
  1100. (cperl-update-syntaxification (point-max) (point-max)))
  1101. (next-single-property-change (point-min) 'here-doc-group nil (point-max)))
  1102. (point-max))]
  1103. ["Narrow to this HERE-DOC" cperl-narrow-to-here-doc
  1104. (eq 'here-doc (progn
  1105. (and cperl-syntaxify-for-menu
  1106. (cperl-update-syntaxification (point) (point)))
  1107. (get-text-property (point) 'syntax-type)))]
  1108. ["Select this HERE-DOC or POD section"
  1109. cperl-select-this-pod-or-here-doc
  1110. (memq (progn
  1111. (and cperl-syntaxify-for-menu
  1112. (cperl-update-syntaxification (point) (point)))
  1113. (get-text-property (point) 'syntax-type))
  1114. '(here-doc pod))]
  1115. "----"
  1116. ["CPerl pretty print (experimental)" cperl-ps-print
  1117. (fboundp 'ps-extend-face-list)]
  1118. "----"
  1119. ["Syntaxify region" cperl-find-pods-heres-region
  1120. (cperl-use-region-p)]
  1121. ["Profile syntaxification" cperl-time-fontification t]
  1122. ["Debug errors in delayed fontification" cperl-emulate-lazy-lock t]
  1123. ["Debug unwind for syntactic scan" cperl-toggle-set-debug-unwind t]
  1124. ["Debug backtrace on syntactic scan (BEWARE!!!)"
  1125. (cperl-toggle-set-debug-unwind nil t) t]
  1126. "----"
  1127. ["Class Hierarchy from TAGS" cperl-tags-hier-init t]
  1128. ;;["Update classes" (cperl-tags-hier-init t) tags-table-list]
  1129. ("Tags"
  1130. ;;; ["Create tags for current file" cperl-etags t]
  1131. ;;; ["Add tags for current file" (cperl-etags t) t]
  1132. ;;; ["Create tags for Perl files in directory" (cperl-etags nil t) t]
  1133. ;;; ["Add tags for Perl files in directory" (cperl-etags t t) t]
  1134. ;;; ["Create tags for Perl files in (sub)directories"
  1135. ;;; (cperl-etags nil 'recursive) t]
  1136. ;;; ["Add tags for Perl files in (sub)directories"
  1137. ;;; (cperl-etags t 'recursive) t])
  1138. ;;;; cperl-write-tags (&optional file erase recurse dir inbuffer)
  1139. ["Create tags for current file" (cperl-write-tags nil t) t]
  1140. ["Add tags for current file" (cperl-write-tags) t]
  1141. ["Create tags for Perl files in directory"
  1142. (cperl-write-tags nil t nil t) t]
  1143. ["Add tags for Perl files in directory"
  1144. (cperl-write-tags nil nil nil t) t]
  1145. ["Create tags for Perl files in (sub)directories"
  1146. (cperl-write-tags nil t t t) t]
  1147. ["Add tags for Perl files in (sub)directories"
  1148. (cperl-write-tags nil nil t t) t]))
  1149. ("Perl docs"
  1150. ["Define word at point" imenu-go-find-at-position
  1151. (fboundp 'imenu-go-find-at-position)]
  1152. ["Help on function" cperl-info-on-command t]
  1153. ["Help on function at point" cperl-info-on-current-command t]
  1154. ["Help on symbol at point" cperl-get-help t]
  1155. ["Perldoc" cperl-perldoc t]
  1156. ["Perldoc on word at point" cperl-perldoc-at-point t]
  1157. ["View manpage of POD in this file" cperl-build-manpage t]
  1158. ["Auto-help on" cperl-lazy-install
  1159. (and (fboundp 'run-with-idle-timer)
  1160. (not cperl-lazy-installed))]
  1161. ["Auto-help off" cperl-lazy-unstall
  1162. (and (fboundp 'run-with-idle-timer)
  1163. cperl-lazy-installed)])
  1164. ("Toggle..."
  1165. ["Auto newline" cperl-toggle-auto-newline t]
  1166. ["Electric parens" cperl-toggle-electric t]
  1167. ["Electric keywords" cperl-toggle-abbrev t]
  1168. ["Fix whitespace on indent" cperl-toggle-construct-fix t]
  1169. ["Auto-help on Perl constructs" cperl-toggle-autohelp t]
  1170. ["Auto fill" auto-fill-mode t])
  1171. ("Indent styles..."
  1172. ["CPerl" (cperl-set-style "CPerl") t]
  1173. ["PerlStyle" (cperl-set-style "PerlStyle") t]
  1174. ["GNU" (cperl-set-style "GNU") t]
  1175. ["C++" (cperl-set-style "C++") t]
  1176. ["K&R" (cperl-set-style "K&R") t]
  1177. ["BSD" (cperl-set-style "BSD") t]
  1178. ["Whitesmith" (cperl-set-style "Whitesmith") t]
  1179. ["Memorize Current" (cperl-set-style "Current") t]
  1180. ["Memorized" (cperl-set-style-back) cperl-old-style])
  1181. ("Micro-docs"
  1182. ["Tips" (describe-variable 'cperl-tips) t]
  1183. ["Problems" (describe-variable 'cperl-problems) t]
  1184. ["Speed" (describe-variable 'cperl-speed) t]
  1185. ["Praise" (describe-variable 'cperl-praise) t]
  1186. ["Faces" (describe-variable 'cperl-tips-faces) t]
  1187. ["CPerl mode" (describe-function 'cperl-mode) t]
  1188. ["CPerl version"
  1189. (message "The version of master-file for this CPerl is %s-Emacs"
  1190. cperl-version) t]))))
  1191. (error nil))
  1192. (autoload 'c-macro-expand "cmacexp"
  1193. "Display the result of expanding all C macros occurring in the region.
  1194. The expansion is entirely correct because it uses the C preprocessor."
  1195. t)
  1196. ;;; These two must be unwound, otherwise take exponential time
  1197. (defconst cperl-maybe-white-and-comment-rex "[ \t\n]*\\(#[^\n]*\n[ \t\n]*\\)*"
  1198. "Regular expression to match optional whitespace with interspersed comments.
  1199. Should contain exactly one group.")
  1200. ;;; This one is tricky to unwind; still very inefficient...
  1201. (defconst cperl-white-and-comment-rex "\\([ \t\n]\\|#[^\n]*\n\\)+"
  1202. "Regular expression to match whitespace with interspersed comments.
  1203. Should contain exactly one group.")
  1204. ;;; Is incorporated in `cperl-imenu--function-name-regexp-perl'
  1205. ;;; `cperl-outline-regexp', `defun-prompt-regexp'.
  1206. ;;; Details of groups in this may be used in several functions; see comments
  1207. ;;; near mentioned above variable(s)...
  1208. ;;; sub($$):lvalue{} sub:lvalue{} Both allowed...
  1209. (defsubst cperl-after-sub-regexp (named attr) ; 9 groups without attr...
  1210. "Match the text after `sub' in a subroutine declaration.
  1211. If NAMED is nil, allows anonymous subroutines. Matches up to the first \":\"
  1212. of attributes (if present), or end of the name or prototype (whatever is
  1213. the last)."
  1214. (concat ; Assume n groups before this...
  1215. "\\(" ; n+1=name-group
  1216. cperl-white-and-comment-rex ; n+2=pre-name
  1217. "\\(::[a-zA-Z_0-9:']+\\|[a-zA-Z_'][a-zA-Z_0-9:']*\\)" ; n+3=name
  1218. "\\)" ; END n+1=name-group
  1219. (if named "" "?")
  1220. "\\(" ; n+4=proto-group
  1221. cperl-maybe-white-and-comment-rex ; n+5=pre-proto
  1222. "\\(([^()]*)\\)" ; n+6=prototype
  1223. "\\)?" ; END n+4=proto-group
  1224. "\\(" ; n+7=attr-group
  1225. cperl-maybe-white-and-comment-rex ; n+8=pre-attr
  1226. "\\(" ; n+9=start-attr
  1227. ":"
  1228. (if attr (concat
  1229. "\\("
  1230. cperl-maybe-white-and-comment-rex ; whitespace-comments
  1231. "\\(\\sw\\|_\\)+" ; attr-name
  1232. ;; attr-arg (1 level of internal parens allowed!)
  1233. "\\((\\(\\\\.\\|[^\\\\()]\\|([^\\\\()]*)\\)*)\\)?"
  1234. "\\(" ; optional : (XXX allows trailing???)
  1235. cperl-maybe-white-and-comment-rex ; whitespace-comments
  1236. ":\\)?"
  1237. "\\)+")
  1238. "[^:]")
  1239. "\\)"
  1240. "\\)?" ; END n+6=proto-group
  1241. ))
  1242. ;;; Details of groups in this are used in `cperl-imenu--create-perl-index'
  1243. ;;; and `cperl-outline-level'.
  1244. ;;;; Was: 2=sub|package; now 2=package-group, 5=package-name 8=sub-name (+3)
  1245. (defvar cperl-imenu--function-name-regexp-perl
  1246. (concat
  1247. "^\\(" ; 1 = all
  1248. "\\([ \t]*package" ; 2 = package-group
  1249. "\\(" ; 3 = package-name-group
  1250. cperl-white-and-comment-rex ; 4 = pre-package-name
  1251. "\\([a-zA-Z_0-9:']+\\)\\)?\\)" ; 5 = package-name
  1252. "\\|"
  1253. "[ \t]*sub"
  1254. (cperl-after-sub-regexp 'named nil) ; 8=name 11=proto 14=attr-start
  1255. cperl-maybe-white-and-comment-rex ; 15=pre-block
  1256. "\\|"
  1257. "=head\\([1-4]\\)[ \t]+" ; 16=level
  1258. "\\([^\n]+\\)$" ; 17=text
  1259. "\\)"))
  1260. (defvar cperl-outline-regexp
  1261. (concat cperl-imenu--function-name-regexp-perl "\\|" "\\`"))
  1262. (defvar cperl-mode-syntax-table nil
  1263. "Syntax table in use in CPerl mode buffers.")
  1264. (defvar cperl-string-syntax-table nil
  1265. "Syntax table in use in CPerl mode string-like chunks.")
  1266. (defsubst cperl-1- (p)
  1267. (max (point-min) (1- p)))
  1268. (defsubst cperl-1+ (p)
  1269. (min (point-max) (1+ p)))
  1270. (if cperl-mode-syntax-table
  1271. ()
  1272. (setq cperl-mode-syntax-table (make-syntax-table))
  1273. (modify-syntax-entry ?\\ "\\" cperl-mode-syntax-table)
  1274. (modify-syntax-entry ?/ "." cperl-mode-syntax-table)
  1275. (modify-syntax-entry ?* "." cperl-mode-syntax-table)
  1276. (modify-syntax-entry ?+ "." cperl-mode-syntax-table)
  1277. (modify-syntax-entry ?- "." cperl-mode-syntax-table)
  1278. (modify-syntax-entry ?= "." cperl-mode-syntax-table)
  1279. (modify-syntax-entry ?% "." cperl-mode-syntax-table)
  1280. (modify-syntax-entry ?< "." cperl-mode-syntax-table)
  1281. (modify-syntax-entry ?> "." cperl-mode-syntax-table)
  1282. (modify-syntax-entry ?& "." cperl-mode-syntax-table)
  1283. (modify-syntax-entry ?$ "\\" cperl-mode-syntax-table)
  1284. (modify-syntax-entry ?\n ">" cperl-mode-syntax-table)
  1285. (modify-syntax-entry ?# "<" cperl-mode-syntax-table)
  1286. (modify-syntax-entry ?' "\"" cperl-mode-syntax-table)
  1287. (modify-syntax-entry ?` "\"" cperl-mode-syntax-table)
  1288. (if cperl-under-as-char
  1289. (modify-syntax-entry ?_ "w" cperl-mode-syntax-table))
  1290. (modify-syntax-entry ?: "_" cperl-mode-syntax-table)
  1291. (modify-syntax-entry ?| "." cperl-mode-syntax-table)
  1292. (setq cperl-string-syntax-table (copy-syntax-table cperl-mode-syntax-table))
  1293. (modify-syntax-entry ?$ "." cperl-string-syntax-table)
  1294. (modify-syntax-entry ?\{ "." cperl-string-syntax-table)
  1295. (modify-syntax-entry ?\} "." cperl-string-syntax-table)
  1296. (modify-syntax-entry ?\" "." cperl-string-syntax-table)
  1297. (modify-syntax-entry ?' "." cperl-string-syntax-table)
  1298. (modify-syntax-entry ?` "." cperl-string-syntax-table)
  1299. (modify-syntax-entry ?# "." cperl-string-syntax-table)) ; (?# comment )
  1300. (defvar cperl-faces-init nil)
  1301. ;; Fix for msb.el
  1302. (defvar cperl-msb-fixed nil)
  1303. (defvar cperl-use-major-mode 'cperl-mode)
  1304. (defvar cperl-font-lock-multiline-start nil)
  1305. (defvar cperl-font-lock-multiline nil)
  1306. (defvar cperl-font-locking nil)
  1307. ;; NB as it stands the code in cperl-mode assumes this only has one
  1308. ;; element. If XEmacs 19 support were dropped, this could all be simplified.
  1309. (defvar cperl-compilation-error-regexp-alist
  1310. ;; This look like a paranoiac regexp: could anybody find a better one? (which WORKS).
  1311. '(("^[^\n]* \\(file\\|at\\) \\([^ \t\n]+\\) [^\n]*line \\([0-9]+\\)[\\., \n]"
  1312. 2 3))
  1313. "Alist that specifies how to match errors in perl output.")
  1314. (defvar compilation-error-regexp-alist)
  1315. ;;;###autoload
  1316. (define-derived-mode cperl-mode prog-mode "CPerl"
  1317. "Major mode for editing Perl code.
  1318. Expression and list commands understand all C brackets.
  1319. Tab indents for Perl code.
  1320. Paragraphs are separated by blank lines only.
  1321. Delete converts tabs to spaces as it moves back.
  1322. Various characters in Perl almost always come in pairs: {}, (), [],
  1323. sometimes <>. When the user types the first, she gets the second as
  1324. well, with optional special formatting done on {}. (Disabled by
  1325. default.) You can always quote (with \\[quoted-insert]) the left
  1326. \"paren\" to avoid the expansion. The processing of < is special,
  1327. since most the time you mean \"less\". CPerl mode tries to guess
  1328. whether you want to type pair <>, and inserts is if it
  1329. appropriate. You can set `cperl-electric-parens-string' to the string that
  1330. contains the parens from the above list you want to be electrical.
  1331. Electricity of parens is controlled by `cperl-electric-parens'.
  1332. You may also set `cperl-electric-parens-mark' to have electric parens
  1333. look for active mark and \"embrace\" a region if possible.'
  1334. CPerl mode provides expansion of the Perl control constructs:
  1335. if, else, elsif, unless, while, until, continue, do,
  1336. for, foreach, formy and foreachmy.
  1337. and POD directives (Disabled by default, see `cperl-electric-keywords'.)
  1338. The user types the keyword immediately followed by a space, which
  1339. causes the construct to be expanded, and the point is positioned where
  1340. she is most likely to want to be. eg. when the user types a space
  1341. following \"if\" the following appears in the buffer: if () { or if ()
  1342. } { } and the cursor is between the parentheses. The user can then
  1343. type some boolean expression within the parens. Having done that,
  1344. typing \\[cperl-linefeed] places you - appropriately indented - on a
  1345. new line between the braces (if you typed \\[cperl-linefeed] in a POD
  1346. directive line, then appropriate number of new lines is inserted).
  1347. If CPerl decides that you want to insert \"English\" style construct like
  1348. bite if angry;
  1349. it will not do any expansion. See also help on variable
  1350. `cperl-extra-newline-before-brace'. (Note that one can switch the
  1351. help message on expansion by setting `cperl-message-electric-keyword'
  1352. to nil.)
  1353. \\[cperl-linefeed] is a convenience replacement for typing carriage
  1354. return. It places you in the next line with proper indentation, or if
  1355. you type it inside the inline block of control construct, like
  1356. foreach (@lines) {print; print}
  1357. and you are on a boundary of a statement inside braces, it will
  1358. transform the construct into a multiline and will place you into an
  1359. appropriately indented blank line. If you need a usual
  1360. `newline-and-indent' behavior, it is on \\[newline-and-indent],
  1361. see documentation on `cperl-electric-linefeed'.
  1362. Use \\[cperl-invert-if-unless] to change a construction of the form
  1363. if (A) { B }
  1364. into
  1365. B if A;
  1366. \\{cperl-mode-map}
  1367. Setting the variable `cperl-font-lock' to t switches on font-lock-mode
  1368. \(even with older Emacsen), `cperl-electric-lbrace-space' to t switches
  1369. on electric space between $ and {, `cperl-electric-parens-string' is
  1370. the string that contains parentheses that should be electric in CPerl
  1371. \(see also `cperl-electric-parens-mark' and `cperl-electric-parens'),
  1372. setting `cperl-electric-keywords' enables electric expansion of
  1373. control structures in CPerl. `cperl-electric-linefeed' governs which
  1374. one of two linefeed behavior is preferable. You can enable all these
  1375. options simultaneously (recommended mode of use) by setting
  1376. `cperl-hairy' to t. In this case you can switch separate options off
  1377. by setting them to `null'. Note that one may undo the extra
  1378. whitespace inserted by semis and braces in `auto-newline'-mode by
  1379. consequent \\[cperl-electric-backspace].
  1380. If your site has perl5 documentation in info format, you can use commands
  1381. \\[cperl-info-on-current-command] and \\[cperl-info-on-command] to access it.
  1382. These keys run commands `cperl-info-on-current-command' and
  1383. `cperl-info-on-command', which one is which is controlled by variable
  1384. `cperl-info-on-command-no-prompt' and `cperl-clobber-lisp-bindings'
  1385. \(in turn affected by `cperl-hairy').
  1386. Even if you have no info-format documentation, short one-liner-style
  1387. help is available on \\[cperl-get-help], and one can run perldoc or
  1388. man via menu.
  1389. It is possible to show this help automatically after some idle time.
  1390. This is regulated by variable `cperl-lazy-help-time'. Default with
  1391. `cperl-hairy' (if the value of `cperl-lazy-help-time' is nil) is 5
  1392. secs idle time . It is also possible to switch this on/off from the
  1393. menu, or via \\[cperl-toggle-autohelp]. Requires `run-with-idle-timer'.
  1394. Use \\[cperl-lineup] to vertically lineup some construction - put the
  1395. beginning of the region at the start of construction, and make region
  1396. span the needed amount of lines.
  1397. Variables `cperl-pod-here-scan', `cperl-pod-here-fontify',
  1398. `cperl-pod-face', `cperl-pod-head-face' control processing of POD and
  1399. here-docs sections. With capable Emaxen results of scan are used
  1400. for indentation too, otherwise they are used for highlighting only.
  1401. Variables controlling indentation style:
  1402. `cperl-tab-always-indent'
  1403. Non-nil means TAB in CPerl mode should always reindent the current line,
  1404. regardless of where in the line point is when the TAB command is used.
  1405. `cperl-indent-left-aligned-comments'
  1406. Non-nil means that the comment starting in leftmost column should indent.
  1407. `cperl-auto-newline'
  1408. Non-nil means automatically newline before and after braces,
  1409. and after colons and semicolons, inserted in Perl code. The following
  1410. \\[cperl-electric-backspace] will remove the inserted whitespace.
  1411. Insertion after colons requires both this variable and
  1412. `cperl-auto-newline-after-colon' set.
  1413. `cperl-auto-newline-after-colon'
  1414. Non-nil means automatically newline even after colons.
  1415. Subject to `cperl-auto-newline' setting.
  1416. `cperl-indent-level'
  1417. Indentation of Perl statements within surrounding block.
  1418. The surrounding block's indentation is the indentation
  1419. of the line on which the open-brace appears.
  1420. `cperl-continued-statement-offset'
  1421. Extra indentation given to a substatement, such as the
  1422. then-clause of an if, or body of a while, or just a statement continuation.
  1423. `cperl-continued-brace-offset'
  1424. Extra indentation given to a brace that starts a substatement.
  1425. This is in addition to `cperl-continued-statement-offset'.
  1426. `cperl-brace-offset'
  1427. Extra indentation for line if it starts with an open brace.
  1428. `cperl-brace-imaginary-offset'
  1429. An open brace following other text is treated as if it the line started
  1430. this far to the right of the actual line indentation.
  1431. `cperl-label-offset'
  1432. Extra indentation for line that is a label.
  1433. `cperl-min-label-indent'
  1434. Minimal indentation for line that is a label.
  1435. Settings for classic indent-styles: K&R BSD=C++ GNU PerlStyle=Whitesmith
  1436. `cperl-indent-level' 5 4 2 4
  1437. `cperl-brace-offset' 0 0 0 0
  1438. `cperl-continued-brace-offset' -5 -4 0 0
  1439. `cperl-label-offset' -5 -4 -2 -4
  1440. `cperl-continued-statement-offset' 5 4 2 4
  1441. CPerl knows several indentation styles, and may bulk set the
  1442. corresponding variables. Use \\[cperl-set-style] to do this. Use
  1443. \\[cperl-set-style-back] to restore the memorized preexisting values
  1444. \(both available from menu). See examples in `cperl-style-examples'.
  1445. Part of the indentation style is how different parts of if/elsif/else
  1446. statements are broken into lines; in CPerl, this is reflected on how
  1447. templates for these constructs are created (controlled by
  1448. `cperl-extra-newline-before-brace'), and how reflow-logic should treat
  1449. \"continuation\" blocks of else/elsif/continue, controlled by the same
  1450. variable, and by `cperl-extra-newline-before-brace-multiline',
  1451. `cperl-merge-trailing-else', `cperl-indent-region-fix-constructs'.
  1452. If `cperl-indent-level' is 0, the statement after opening brace in
  1453. column 0 is indented on
  1454. `cperl-brace-offset'+`cperl-continued-statement-offset'.
  1455. Turning on CPerl mode calls the hooks in the variable `cperl-mode-hook'
  1456. with no args.
  1457. DO NOT FORGET to read micro-docs (available from `Perl' menu)
  1458. or as help on variables `cperl-tips', `cperl-problems',
  1459. `cperl-praise', `cperl-speed'."
  1460. (if (cperl-val 'cperl-electric-linefeed)
  1461. (progn
  1462. (local-set-key "\C-J" 'cperl-linefeed)
  1463. (local-set-key "\C-C\C-J" 'newline-and-indent)))
  1464. (if (and
  1465. (cperl-val 'cperl-clobber-lisp-bindings)
  1466. (cperl-val 'cperl-info-on-command-no-prompt))
  1467. (progn
  1468. ;; don't clobber the backspace binding:
  1469. (cperl-define-key "\C-hf" 'cperl-info-on-current-command [(control h) f])
  1470. (cperl-define-key "\C-c\C-hf" 'cperl-info-on-command
  1471. [(control c) (control h) f])))
  1472. (let ((prev-a-c abbrevs-changed))
  1473. (define-abbrev-table 'cperl-mode-abbrev-table '(
  1474. ("if" "if" cperl-electric-keyword 0)
  1475. ("elsif" "elsif" cperl-electric-keyword 0)
  1476. ("while" "while" cperl-electric-keyword 0)
  1477. ("until" "until" cperl-electric-keyword 0)
  1478. ("unless" "unless" cperl-electric-keyword 0)
  1479. ("else" "else" cperl-electric-else 0)
  1480. ("continue" "continue" cperl-electric-else 0)
  1481. ("for" "for" cperl-electric-keyword 0)
  1482. ("foreach" "foreach" cperl-electric-keyword 0)
  1483. ("formy" "formy" cperl-electric-keyword 0)
  1484. ("foreachmy" "foreachmy" cperl-electric-keyword 0)
  1485. ("do" "do" cperl-electric-keyword 0)
  1486. ("=pod" "=pod" cperl-electric-pod 0)
  1487. ("=over" "=over" cperl-electric-pod 0)
  1488. ("=head1" "=head1" cperl-electric-pod 0)
  1489. ("=head2" "=head2" cperl-electric-pod 0)
  1490. ("pod" "pod" cperl-electric-pod 0)
  1491. ("over" "over" cperl-electric-pod 0)
  1492. ("head1" "head1" cperl-electric-pod 0)
  1493. ("head2" "head2" cperl-electric-pod 0)))
  1494. (setq abbrevs-changed prev-a-c))
  1495. (setq local-abbrev-table cperl-mode-abbrev-table)
  1496. (if (cperl-val 'cperl-electric-keywords)
  1497. (abbrev-mode 1))
  1498. (set-syntax-table cperl-mode-syntax-table)
  1499. ;; Until Emacs is multi-threaded, we do not actually need it local:
  1500. (make-local-variable 'cperl-font-lock-multiline-start)
  1501. (make-local-variable 'cperl-font-locking)
  1502. (make-local-variable 'outline-regexp)
  1503. ;; (setq outline-regexp imenu-example--function-name-regexp-perl)
  1504. (setq outline-regexp cperl-outline-regexp)
  1505. (make-local-variable 'outline-level)
  1506. (setq outline-level 'cperl-outline-level)
  1507. (make-local-variable 'paragraph-start)
  1508. (setq paragraph-start (concat "^$\\|" page-delimiter))
  1509. (make-local-variable 'paragraph-separate)
  1510. (setq paragraph-separate paragraph-start)
  1511. (make-local-variable 'paragraph-ignore-fill-prefix)
  1512. (setq paragraph-ignore-fill-prefix t)
  1513. (if (featurep 'xemacs)
  1514. (progn
  1515. (make-local-variable 'paren-backwards-message)
  1516. (set 'paren-backwards-message t)))
  1517. (make-local-variable 'indent-line-function)
  1518. (setq indent-line-function 'cperl-indent-line)
  1519. (make-local-variable 'require-final-newline)
  1520. (setq require-final-newline mode-require-final-newline)
  1521. (make-local-variable 'comment-start)
  1522. (setq comment-start "# ")
  1523. (make-local-variable 'comment-end)
  1524. (setq comment-end "")
  1525. (make-local-variable 'comment-column)
  1526. (setq comment-column cperl-comment-column)
  1527. (make-local-variable 'comment-start-skip)
  1528. (setq comment-start-skip "#+ *")
  1529. (make-local-variable 'defun-prompt-regexp)
  1530. ;;; "[ \t]*sub"
  1531. ;;; (cperl-after-sub-regexp 'named nil) ; 8=name 11=proto 14=attr-start
  1532. ;;; cperl-maybe-white-and-comment-rex ; 15=pre-block
  1533. (setq defun-prompt-regexp
  1534. (concat "^[ \t]*\\(sub"
  1535. (cperl-after-sub-regexp 'named 'attr-groups)
  1536. "\\|" ; per toke.c
  1537. "\\(BEGIN\\|CHECK\\|INIT\\|END\\|AUTOLOAD\\|DESTROY\\)"
  1538. "\\)"
  1539. cperl-maybe-white-and-comment-rex))
  1540. (make-local-variable 'comment-indent-function)
  1541. (setq comment-indent-function 'cperl-comment-indent)
  1542. (and (boundp 'fill-paragraph-function)
  1543. (progn
  1544. (make-local-variable 'fill-paragraph-function)
  1545. (set 'fill-paragraph-function 'cperl-fill-paragraph)))
  1546. (make-local-variable 'parse-sexp-ignore-comments)
  1547. (setq parse-sexp-ignore-comments t)
  1548. (make-local-variable 'indent-region-function)
  1549. (setq indent-region-function 'cperl-indent-region)
  1550. ;;(setq auto-fill-function 'cperl-do-auto-fill) ; Need to switch on and off!
  1551. (make-local-variable 'imenu-create-index-function)
  1552. (setq imenu-create-index-function
  1553. (function cperl-imenu--create-perl-index))
  1554. (make-local-variable 'imenu-sort-function)
  1555. (setq imenu-sort-function nil)
  1556. (make-local-variable 'vc-rcs-header)
  1557. (set 'vc-rcs-header cperl-vc-rcs-header)
  1558. (make-local-variable 'vc-sccs-header)
  1559. (set 'vc-sccs-header cperl-vc-sccs-header)
  1560. (when (featurep 'xemacs)
  1561. ;; This one is obsolete...
  1562. (make-local-variable 'vc-header-alist)
  1563. (set 'vc-header-alist (or cperl-vc-header-alist ; Avoid warning
  1564. `((SCCS ,(car cperl-vc-sccs-header))
  1565. (RCS ,(car cperl-vc-rcs-header))))))
  1566. (cond ((boundp 'compilation-error-regexp-alist-alist);; xemacs 20.x
  1567. (make-local-variable 'compilation-error-regexp-alist-alist)
  1568. (set 'compilation-error-regexp-alist-alist
  1569. (cons (cons 'cperl (car cperl-compilation-error-regexp-alist))
  1570. (symbol-value 'compilation-error-regexp-alist-alist)))
  1571. (if (fboundp 'compilation-build-compilation-error-regexp-alist)
  1572. (let ((f 'compilation-build-compilation-error-regexp-alist))
  1573. (funcall f))
  1574. (make-local-variable 'compilation-error-regexp-alist)
  1575. (push 'cperl compilation-error-regexp-alist)))
  1576. ((boundp 'compilation-error-regexp-alist);; xemacs 19.x
  1577. (make-local-variable 'compilation-error-regexp-alist)
  1578. (set 'compilation-error-regexp-alist
  1579. (append cperl-compilation-error-regexp-alist
  1580. (symbol-value 'compilation-error-regexp-alist)))))
  1581. (make-local-variable 'font-lock-defaults)
  1582. (setq font-lock-defaults
  1583. (cond
  1584. ((string< emacs-version "19.30")
  1585. '(cperl-font-lock-keywords-2 nil nil ((?_ . "w"))))
  1586. ((string< emacs-version "19.33") ; Which one to use?
  1587. '((cperl-font-lock-keywords
  1588. cperl-font-lock-keywords-1
  1589. cperl-font-lock-keywords-2) nil nil ((?_ . "w"))))
  1590. (t
  1591. '((cperl-load-font-lock-keywords
  1592. cperl-load-font-lock-keywords-1
  1593. cperl-load-font-lock-keywords-2) nil nil ((?_ . "w"))))))
  1594. (make-local-variable 'cperl-syntax-state)
  1595. (setq cperl-syntax-state nil) ; reset syntaxification cache
  1596. (if cperl-use-syntax-table-text-property
  1597. (if (boundp 'syntax-propertize-function)
  1598. (progn
  1599. ;; Reset syntaxification cache.
  1600. (set (make-local-variable 'cperl-syntax-done-to) nil)
  1601. (set (make-local-variable 'syntax-propertize-function)
  1602. (lambda (start end)
  1603. (goto-char start)
  1604. ;; Even if cperl-fontify-syntaxically has already gone
  1605. ;; beyond `start', syntax-propertize has just removed
  1606. ;; syntax-table properties between start and end, so we have
  1607. ;; to re-apply them.
  1608. (setq cperl-syntax-done-to start)
  1609. (cperl-fontify-syntaxically end))))
  1610. (make-local-variable 'parse-sexp-lookup-properties)
  1611. ;; Do not introduce variable if not needed, we check it!
  1612. (set 'parse-sexp-lookup-properties t)
  1613. ;; Fix broken font-lock:
  1614. (or (boundp 'font-lock-unfontify-region-function)
  1615. (set 'font-lock-unfontify-region-function
  1616. 'font-lock-default-unfontify-region))
  1617. (unless (featurep 'xemacs) ; Our: just a plug for wrong font-lock
  1618. (make-local-variable 'font-lock-unfontify-region-function)
  1619. (set 'font-lock-unfontify-region-function ; not present with old Emacs
  1620. 'cperl-font-lock-unfontify-region-function))
  1621. (make-local-variable 'cperl-syntax-done-to)
  1622. (setq cperl-syntax-done-to nil) ; reset syntaxification cache
  1623. (make-local-variable 'font-lock-syntactic-keywords)
  1624. (setq font-lock-syntactic-keywords
  1625. (if cperl-syntaxify-by-font-lock
  1626. '((cperl-fontify-syntaxically))
  1627. ;; unless font-lock-syntactic-keywords, font-lock (pre-22.1)
  1628. ;; used to ignore syntax-table text-properties. (t) is a hack
  1629. ;; to make font-lock think that font-lock-syntactic-keywords
  1630. ;; are defined.
  1631. '(t)))))
  1632. (if (boundp 'font-lock-multiline) ; Newer font-lock; use its facilities
  1633. (progn
  1634. (setq cperl-font-lock-multiline t) ; Not localized...
  1635. (set (make-local-variable 'font-lock-multiline) t))
  1636. (make-local-variable 'font-lock-fontify-region-function)
  1637. (set 'font-lock-fontify-region-function ; not present with old Emacs
  1638. 'cperl-font-lock-fontify-region-function))
  1639. (make-local-variable 'font-lock-fontify-region-function)
  1640. (set 'font-lock-fontify-region-function ; not present with old Emacs
  1641. 'cperl-font-lock-fontify-region-function)
  1642. (make-local-variable 'cperl-old-style)
  1643. (if (boundp 'normal-auto-fill-function) ; 19.33 and later
  1644. (set (make-local-variable 'normal-auto-fill-function)
  1645. 'cperl-do-auto-fill)
  1646. (or (fboundp 'cperl-old-auto-fill-mode)
  1647. (progn
  1648. (fset 'cperl-old-auto-fill-mode (symbol-function 'auto-fill-mode))
  1649. (defun auto-fill-mode (&optional arg)
  1650. (interactive "P")
  1651. (eval '(cperl-old-auto-fill-mode arg)) ; Avoid a warning
  1652. (and auto-fill-function (memq major-mode '(perl-mode cperl-mode))
  1653. (setq auto-fill-function 'cperl-do-auto-fill))))))
  1654. (if (cperl-enable-font-lock)
  1655. (if (cperl-val 'cperl-font-lock)
  1656. (progn (or cperl-faces-init (cperl-init-faces))
  1657. (font-lock-mode 1))))
  1658. (set (make-local-variable 'facemenu-add-face-function)
  1659. 'cperl-facemenu-add-face-function) ; XXXX What this guy is for???
  1660. (and (boundp 'msb-menu-cond)
  1661. (not cperl-msb-fixed)
  1662. (cperl-msb-fix))
  1663. (if (featurep 'easymenu)
  1664. (easy-menu-add cperl-menu)) ; A NOP in Emacs.
  1665. (run-mode-hooks 'cperl-mode-hook)
  1666. (if cperl-hook-after-change
  1667. (add-hook 'after-change-functions 'cperl-after-change-function nil t))
  1668. ;; After hooks since fontification will break this
  1669. (if cperl-pod-here-scan
  1670. (or cperl-syntaxify-by-font-lock
  1671. (progn (or cperl-faces-init (cperl-init-faces-weak))
  1672. (cperl-find-pods-heres)))))
  1673. ;; Fix for perldb - make default reasonable
  1674. (defun cperl-db ()
  1675. (interactive)
  1676. (require 'gud)
  1677. (perldb (read-from-minibuffer "Run perldb (like this): "
  1678. (if (consp gud-perldb-history)
  1679. (car gud-perldb-history)
  1680. (concat "perl " ;;(file-name-nondirectory
  1681. ;; I have problems
  1682. ;; in OS/2
  1683. ;; otherwise
  1684. (buffer-file-name)))
  1685. nil nil
  1686. '(gud-perldb-history . 1))))
  1687. (defun cperl-msb-fix ()
  1688. ;; Adds perl files to msb menu, supposes that msb is already loaded
  1689. (setq cperl-msb-fixed t)
  1690. (let* ((l (length msb-menu-cond))
  1691. (last (nth (1- l) msb-menu-cond))
  1692. (precdr (nthcdr (- l 2) msb-menu-cond)) ; cdr of this is last
  1693. (handle (1- (nth 1 last))))
  1694. (setcdr precdr (list
  1695. (list
  1696. '(memq major-mode '(cperl-mode perl-mode))
  1697. handle
  1698. "Perl Files (%d)")
  1699. last))))
  1700. ;; This is used by indent-for-comment
  1701. ;; to decide how much to indent a comment in CPerl code
  1702. ;; based on its context. Do fallback if comment is found wrong.
  1703. (defvar cperl-wrong-comment)
  1704. (defvar cperl-st-cfence '(14)) ; Comment-fence
  1705. (defvar cperl-st-sfence '(15)) ; String-fence
  1706. (defvar cperl-st-punct '(1))
  1707. (defvar cperl-st-word '(2))
  1708. (defvar cperl-st-bra '(4 . ?\>))
  1709. (defvar cperl-st-ket '(5 . ?\<))
  1710. (defun cperl-comment-indent () ; called at point at supposed comment
  1711. (let ((p (point)) (c (current-column)) was phony)
  1712. (if (and (not cperl-indent-comment-at-column-0)
  1713. (looking-at "^#"))
  1714. 0 ; Existing comment at bol stays there.
  1715. ;; Wrong comment found
  1716. (save-excursion
  1717. (setq was (cperl-to-comment-or-eol)
  1718. phony (eq (get-text-property (point) 'syntax-table)
  1719. cperl-st-cfence))
  1720. (if phony
  1721. (progn ; Too naive???
  1722. (re-search-forward "#\\|$") ; Hmm, what about embedded #?
  1723. (if (eq (preceding-char) ?\#)
  1724. (forward-char -1))
  1725. (setq was nil)))
  1726. (if (= (point) p) ; Our caller found a correct place
  1727. (progn
  1728. (skip-chars-backward " \t")
  1729. (setq was (current-column))
  1730. (if (eq was 0)
  1731. comment-column
  1732. (max (1+ was) ; Else indent at comment column
  1733. comment-column)))
  1734. ;; No, the caller found a random place; we need to edit ourselves
  1735. (if was nil
  1736. (insert comment-start)
  1737. (backward-char (length comment-start)))
  1738. (setq cperl-wrong-comment t)
  1739. (cperl-make-indent comment-column 1) ; Indent min 1
  1740. c)))))
  1741. ;;;(defun cperl-comment-indent-fallback ()
  1742. ;;; "Is called if the standard comment-search procedure fails.
  1743. ;;;Point is at start of real comment."
  1744. ;;; (let ((c (current-column)) target cnt prevc)
  1745. ;;; (if (= c comment-column) nil
  1746. ;;; (setq cnt (skip-chars-backward "[ \t]"))
  1747. ;;; (setq target (max (1+ (setq prevc
  1748. ;;; (current-column))) ; Else indent at comment column
  1749. ;;; comment-column))
  1750. ;;; (if (= c comment-column) nil
  1751. ;;; (delete-backward-char cnt)
  1752. ;;; (while (< prevc target)
  1753. ;;; (insert "\t")
  1754. ;;; (setq prevc (current-column)))
  1755. ;;; (if (> prevc target) (progn (delete-char -1) (setq prevc (current-column))))
  1756. ;;; (while (< prevc target)
  1757. ;;; (insert " ")
  1758. ;;; (setq prevc (current-column)))))))
  1759. (defun cperl-indent-for-comment ()
  1760. "Substitute for `indent-for-comment' in CPerl."
  1761. (interactive)
  1762. (let (cperl-wrong-comment)
  1763. (indent-for-comment)
  1764. (if cperl-wrong-comment ; set by `cperl-comment-indent'
  1765. (progn (cperl-to-comment-or-eol)
  1766. (forward-char (length comment-start))))))
  1767. (defun cperl-comment-region (b e arg)
  1768. "Comment or uncomment each line in the region in CPerl mode.
  1769. See `comment-region'."
  1770. (interactive "r\np")
  1771. (let ((comment-start "#"))
  1772. (comment-region b e arg)))
  1773. (defun cperl-uncomment-region (b e arg)
  1774. "Uncomment or comment each line in the region in CPerl mode.
  1775. See `comment-region'."
  1776. (interactive "r\np")
  1777. (let ((comment-start "#"))
  1778. (comment-region b e (- arg))))
  1779. (defvar cperl-brace-recursing nil)
  1780. (defun cperl-electric-brace (arg &optional only-before)
  1781. "Insert character and correct line's indentation.
  1782. If ONLY-BEFORE and `cperl-auto-newline', will insert newline before the
  1783. place (even in empty line), but not after. If after \")\" and the inserted
  1784. char is \"{\", insert extra newline before only if
  1785. `cperl-extra-newline-before-brace'."
  1786. (interactive "P")
  1787. (let (insertpos
  1788. (other-end (if (and cperl-electric-parens-mark
  1789. (cperl-mark-active)
  1790. (< (mark) (point)))
  1791. (mark)
  1792. nil)))
  1793. (if (and other-end
  1794. (not cperl-brace-recursing)
  1795. (cperl-val 'cperl-electric-parens)
  1796. (>= (save-excursion (cperl-to-comment-or-eol) (point)) (point)))
  1797. ;; Need to insert a matching pair
  1798. (progn
  1799. (save-excursion
  1800. (setq insertpos (point-marker))
  1801. (goto-char other-end)
  1802. (setq last-command-event ?\{)
  1803. (cperl-electric-lbrace arg insertpos))
  1804. (forward-char 1))
  1805. ;; Check whether we close something "usual" with `}'
  1806. (if (and (eq last-command-event ?\})
  1807. (not
  1808. (condition-case nil
  1809. (save-excursion
  1810. (up-list (- (prefix-numeric-value arg)))
  1811. ;;(cperl-after-block-p (point-min))
  1812. (or (cperl-after-expr-p nil "{;)")
  1813. ;; after sub, else, continue
  1814. (cperl-after-block-p nil 'pre)))
  1815. (error nil))))
  1816. ;; Just insert the guy
  1817. (self-insert-command (prefix-numeric-value arg))
  1818. (if (and (not arg) ; No args, end (of empty line or auto)
  1819. (eolp)
  1820. (or (and (null only-before)
  1821. (save-excursion
  1822. (skip-chars-backward " \t")
  1823. (bolp)))
  1824. (and (eq last-command-event ?\{) ; Do not insert newline
  1825. ;; if after ")" and `cperl-extra-newline-before-brace'
  1826. ;; is nil, do not insert extra newline.
  1827. (not cperl-extra-newline-before-brace)
  1828. (save-excursion
  1829. (skip-chars-backward " \t")
  1830. (eq (preceding-char) ?\))))
  1831. (if cperl-auto-newline
  1832. (progn (cperl-indent-line) (newline) t) nil)))
  1833. (progn
  1834. (self-insert-command (prefix-numeric-value arg))
  1835. (cperl-indent-line)
  1836. (if cperl-auto-newline
  1837. (setq insertpos (1- (point))))
  1838. (if (and cperl-auto-newline (null only-before))
  1839. (progn
  1840. (newline)
  1841. (cperl-indent-line)))
  1842. (save-excursion
  1843. (if insertpos (progn (goto-char insertpos)
  1844. (search-forward (make-string
  1845. 1 last-command-event))
  1846. (setq insertpos (1- (point)))))
  1847. (delete-char -1))))
  1848. (if insertpos
  1849. (save-excursion
  1850. (goto-char insertpos)
  1851. (self-insert-command (prefix-numeric-value arg)))
  1852. (self-insert-command (prefix-numeric-value arg)))))))
  1853. (defun cperl-electric-lbrace (arg &optional end)
  1854. "Insert character, correct line's indentation, correct quoting by space."
  1855. (interactive "P")
  1856. (let ((cperl-brace-recursing t)
  1857. (cperl-auto-newline cperl-auto-newline)
  1858. (other-end (or end
  1859. (if (and cperl-electric-parens-mark
  1860. (cperl-mark-active)
  1861. (> (mark) (point)))
  1862. (save-excursion
  1863. (goto-char (mark))
  1864. (point-marker))
  1865. nil)))
  1866. pos after)
  1867. (and (cperl-val 'cperl-electric-lbrace-space)
  1868. (eq (preceding-char) ?$)
  1869. (save-excursion
  1870. (skip-chars-backward "$")
  1871. (looking-at "\\(\\$\\$\\)*\\$\\([^\\$]\\|$\\)"))
  1872. (insert ?\s))
  1873. ;; Check whether we are in comment
  1874. (if (and
  1875. (save-excursion
  1876. (beginning-of-line)
  1877. (not (looking-at "[ \t]*#")))
  1878. (cperl-after-expr-p nil "{;)"))
  1879. nil
  1880. (setq cperl-auto-newline nil))
  1881. (cperl-electric-brace arg)
  1882. (and (cperl-val 'cperl-electric-parens)
  1883. (eq last-command-event ?{)
  1884. (memq last-command-event
  1885. (append cperl-electric-parens-string nil))
  1886. (or (if other-end (goto-char (marker-position other-end)))
  1887. t)
  1888. (setq last-command-event ?} pos (point))
  1889. (progn (cperl-electric-brace arg t)
  1890. (goto-char pos)))))
  1891. (defun cperl-electric-paren (arg)
  1892. "Insert an opening parenthesis or a matching pair of parentheses.
  1893. See `cperl-electric-parens'."
  1894. (interactive "P")
  1895. (let ((beg (point-at-bol))
  1896. (other-end (if (and cperl-electric-parens-mark
  1897. (cperl-mark-active)
  1898. (> (mark) (point)))
  1899. (save-excursion
  1900. (goto-char (mark))
  1901. (point-marker))
  1902. nil)))
  1903. (if (and (cperl-val 'cperl-electric-parens)
  1904. (memq last-command-event
  1905. (append cperl-electric-parens-string nil))
  1906. (>= (save-excursion (cperl-to-comment-or-eol) (point)) (point))
  1907. ;;(not (save-excursion (search-backward "#" beg t)))
  1908. (if (eq last-command-event ?<)
  1909. (progn
  1910. ;; This code is too electric, see Bug#3943.
  1911. ;; (and abbrev-mode ; later it is too late, may be after `for'
  1912. ;; (expand-abbrev))
  1913. (cperl-after-expr-p nil "{;(,:="))
  1914. 1))
  1915. (progn
  1916. (self-insert-command (prefix-numeric-value arg))
  1917. (if other-end (goto-char (marker-position other-end)))
  1918. (insert (make-string
  1919. (prefix-numeric-value arg)
  1920. (cdr (assoc last-command-event '((?{ .?})
  1921. (?[ . ?])
  1922. (?( . ?))
  1923. (?< . ?>))))))
  1924. (forward-char (- (prefix-numeric-value arg))))
  1925. (self-insert-command (prefix-numeric-value arg)))))
  1926. (defun cperl-electric-rparen (arg)
  1927. "Insert a matching pair of parentheses if marking is active.
  1928. If not, or if we are not at the end of marking range, would self-insert.
  1929. Affected by `cperl-electric-parens'."
  1930. (interactive "P")
  1931. (let ((beg (point-at-bol))
  1932. (other-end (if (and cperl-electric-parens-mark
  1933. (cperl-val 'cperl-electric-parens)
  1934. (memq last-command-event
  1935. (append cperl-electric-parens-string nil))
  1936. (cperl-mark-active)
  1937. (< (mark) (point)))
  1938. (mark)
  1939. nil))
  1940. p)
  1941. (if (and other-end
  1942. (cperl-val 'cperl-electric-parens)
  1943. (memq last-command-event '( ?\) ?\] ?\} ?\> ))
  1944. (>= (save-excursion (cperl-to-comment-or-eol) (point)) (point))
  1945. ;;(not (save-excursion (search-backward "#" beg t)))
  1946. )
  1947. (progn
  1948. (self-insert-command (prefix-numeric-value arg))
  1949. (setq p (point))
  1950. (if other-end (goto-char other-end))
  1951. (insert (make-string
  1952. (prefix-numeric-value arg)
  1953. (cdr (assoc last-command-event '((?\} . ?\{)
  1954. (?\] . ?\[)
  1955. (?\) . ?\()
  1956. (?\> . ?\<))))))
  1957. (goto-char (1+ p)))
  1958. (self-insert-command (prefix-numeric-value arg)))))
  1959. (defun cperl-electric-keyword ()
  1960. "Insert a construction appropriate after a keyword.
  1961. Help message may be switched off by setting `cperl-message-electric-keyword'
  1962. to nil."
  1963. (let ((beg (point-at-bol))
  1964. (dollar (and (eq last-command-event ?$)
  1965. (eq this-command 'self-insert-command)))
  1966. (delete (and (memq last-command-event '(?\s ?\n ?\t ?\f))
  1967. (memq this-command '(self-insert-command newline))))
  1968. my do)
  1969. (and (save-excursion
  1970. (condition-case nil
  1971. (progn
  1972. (backward-sexp 1)
  1973. (setq do (looking-at "do\\>")))
  1974. (error nil))
  1975. (cperl-after-expr-p nil "{;:"))
  1976. (save-excursion
  1977. (not
  1978. (re-search-backward
  1979. "[#\"'`]\\|\\<q\\(\\|[wqxr]\\)\\>"
  1980. beg t)))
  1981. (save-excursion (or (not (re-search-backward "^=" nil t))
  1982. (or
  1983. (looking-at "=cut")
  1984. (and cperl-use-syntax-table-text-property
  1985. (not (eq (get-text-property (point)
  1986. 'syntax-type)
  1987. 'pod))))))
  1988. (save-excursion (forward-sexp -1)
  1989. (not (memq (following-char) (append "$@%&*" nil))))
  1990. (progn
  1991. (and (eq (preceding-char) ?y)
  1992. (progn ; "foreachmy"
  1993. (forward-char -2)
  1994. (insert " ")
  1995. (forward-char 2)
  1996. (setq my t dollar t
  1997. delete
  1998. (memq this-command '(self-insert-command newline)))))
  1999. (and dollar (insert " $"))
  2000. (cperl-indent-line)
  2001. ;;(insert " () {\n}")
  2002. (cond
  2003. (cperl-extra-newline-before-brace
  2004. (insert (if do "\n" " ()\n"))
  2005. (insert "{")
  2006. (cperl-indent-line)
  2007. (insert "\n")
  2008. (cperl-indent-line)
  2009. (insert "\n}")
  2010. (and do (insert " while ();")))
  2011. (t
  2012. (insert (if do " {\n} while ();" " () {\n}"))))
  2013. (or (looking-at "[ \t]\\|$") (insert " "))
  2014. (cperl-indent-line)
  2015. (if dollar (progn (search-backward "$")
  2016. (if my
  2017. (forward-char 1)
  2018. (delete-char 1)))
  2019. (search-backward ")")
  2020. (if (eq last-command-event ?\()
  2021. (progn ; Avoid "if (())"
  2022. (delete-backward-char 1)
  2023. (delete-backward-char -1))))
  2024. (if delete
  2025. (cperl-putback-char cperl-del-back-ch))
  2026. (if cperl-message-electric-keyword
  2027. (message "Precede char by C-q to avoid expansion"))))))
  2028. (defun cperl-ensure-newlines (n &optional pos)
  2029. "Make sure there are N newlines after the point."
  2030. (or pos (setq pos (point)))
  2031. (if (looking-at "\n")
  2032. (forward-char 1)
  2033. (insert "\n"))
  2034. (if (> n 1)
  2035. (cperl-ensure-newlines (1- n) pos)
  2036. (goto-char pos)))
  2037. (defun cperl-electric-pod ()
  2038. "Insert a POD chunk appropriate after a =POD directive."
  2039. (let ((delete (and (memq last-command-event '(?\s ?\n ?\t ?\f))
  2040. (memq this-command '(self-insert-command newline))))
  2041. head1 notlast name p really-delete over)
  2042. (and (save-excursion
  2043. (forward-word -1)
  2044. (and
  2045. (eq (preceding-char) ?=)
  2046. (progn
  2047. (setq head1 (looking-at "head1\\>[ \t]*$"))
  2048. (setq over (and (looking-at "over\\>[ \t]*$")
  2049. (not (looking-at "over[ \t]*\n\n\n*=item\\>"))))
  2050. (forward-char -1)
  2051. (bolp))
  2052. (or
  2053. (get-text-property (point) 'in-pod)
  2054. (cperl-after-expr-p nil "{;:")
  2055. (and (re-search-backward "\\(\\`\n?\\|^\n\\)=\\sw+" (point-min) t)
  2056. (not (looking-at "\n*=cut"))
  2057. (or (not cperl-use-syntax-table-text-property)
  2058. (eq (get-text-property (point) 'syntax-type) 'pod))))))
  2059. (progn
  2060. (save-excursion
  2061. (setq notlast (re-search-forward "^\n=" nil t)))
  2062. (or notlast
  2063. (progn
  2064. (insert "\n\n=cut")
  2065. (cperl-ensure-newlines 2)
  2066. (forward-word -2)
  2067. (if (and head1
  2068. (not
  2069. (save-excursion
  2070. (forward-char -1)
  2071. (re-search-backward "\\(\\`\n?\\|\n\n\\)=head1\\>"
  2072. nil t)))) ; Only one
  2073. (progn
  2074. (forward-word 1)
  2075. (setq name (file-name-sans-extension
  2076. (file-name-nondirectory (buffer-file-name)))
  2077. p (point))
  2078. (insert " NAME\n\n" name
  2079. " - \n\n=head1 SYNOPSIS\n\n\n\n"
  2080. "=head1 DESCRIPTION")
  2081. (cperl-ensure-newlines 4)
  2082. (goto-char p)
  2083. (forward-word 2)
  2084. (end-of-line)
  2085. (setq really-delete t))
  2086. (forward-word 1))))
  2087. (if over
  2088. (progn
  2089. (setq p (point))
  2090. (insert "\n\n=item \n\n\n\n"
  2091. "=back")
  2092. (cperl-ensure-newlines 2)
  2093. (goto-char p)
  2094. (forward-word 1)
  2095. (end-of-line)
  2096. (setq really-delete t)))
  2097. (if (and delete really-delete)
  2098. (cperl-putback-char cperl-del-back-ch))))))
  2099. (defun cperl-electric-else ()
  2100. "Insert a construction appropriate after a keyword.
  2101. Help message may be switched off by setting `cperl-message-electric-keyword'
  2102. to nil."
  2103. (let ((beg (point-at-bol)))
  2104. (and (save-excursion
  2105. (backward-sexp 1)
  2106. (cperl-after-expr-p nil "{;:"))
  2107. (save-excursion
  2108. (not
  2109. (re-search-backward
  2110. "[#\"'`]\\|\\<q\\(\\|[wqxr]\\)\\>"
  2111. beg t)))
  2112. (save-excursion (or (not (re-search-backward "^=" nil t))
  2113. (looking-at "=cut")
  2114. (and cperl-use-syntax-table-text-property
  2115. (not (eq (get-text-property (point)
  2116. 'syntax-type)
  2117. 'pod)))))
  2118. (progn
  2119. (cperl-indent-line)
  2120. ;;(insert " {\n\n}")
  2121. (cond
  2122. (cperl-extra-newline-before-brace
  2123. (insert "\n")
  2124. (insert "{")
  2125. (cperl-indent-line)
  2126. (insert "\n\n}"))
  2127. (t
  2128. (insert " {\n\n}")))
  2129. (or (looking-at "[ \t]\\|$") (insert " "))
  2130. (cperl-indent-line)
  2131. (forward-line -1)
  2132. (cperl-indent-line)
  2133. (cperl-putback-char cperl-del-back-ch)
  2134. (setq this-command 'cperl-electric-else)
  2135. (if cperl-message-electric-keyword
  2136. (message "Precede char by C-q to avoid expansion"))))))
  2137. (defun cperl-linefeed ()
  2138. "Go to end of line, open a new line and indent appropriately.
  2139. If in POD, insert appropriate lines."
  2140. (interactive)
  2141. (let ((beg (point-at-bol))
  2142. (end (point-at-eol))
  2143. (pos (point)) start over cut res)
  2144. (if (and ; Check if we need to split:
  2145. ; i.e., on a boundary and inside "{...}"
  2146. (save-excursion (cperl-to-comment-or-eol)
  2147. (>= (point) pos)) ; Not in a comment
  2148. (or (save-excursion
  2149. (skip-chars-backward " \t" beg)
  2150. (forward-char -1)
  2151. (looking-at "[;{]")) ; After { or ; + spaces
  2152. (looking-at "[ \t]*}") ; Before }
  2153. (re-search-forward "\\=[ \t]*;" end t)) ; Before spaces + ;
  2154. (save-excursion
  2155. (and
  2156. (eq (car (parse-partial-sexp pos end -1)) -1)
  2157. ; Leave the level of parens
  2158. (looking-at "[,; \t]*\\($\\|#\\)") ; Comma to allow anon subr
  2159. ; Are at end
  2160. (cperl-after-block-p (point-min))
  2161. (progn
  2162. (backward-sexp 1)
  2163. (setq start (point-marker))
  2164. (<= start pos))))) ; Redundant? Are after the
  2165. ; start of parens group.
  2166. (progn
  2167. (skip-chars-backward " \t")
  2168. (or (memq (preceding-char) (append ";{" nil))
  2169. (insert ";"))
  2170. (insert "\n")
  2171. (forward-line -1)
  2172. (cperl-indent-line)
  2173. (goto-char start)
  2174. (or (looking-at "{[ \t]*$") ; If there is a statement
  2175. ; before, move it to separate line
  2176. (progn
  2177. (forward-char 1)
  2178. (insert "\n")
  2179. (cperl-indent-line)))
  2180. (forward-line 1) ; We are on the target line
  2181. (cperl-indent-line)
  2182. (beginning-of-line)
  2183. (or (looking-at "[ \t]*}[,; \t]*$") ; If there is a statement
  2184. ; after, move it to separate line
  2185. (progn
  2186. (end-of-line)
  2187. (search-backward "}" beg)
  2188. (skip-chars-backward " \t")
  2189. (or (memq (preceding-char) (append ";{" nil))
  2190. (insert ";"))
  2191. (insert "\n")
  2192. (cperl-indent-line)
  2193. (forward-line -1)))
  2194. (forward-line -1) ; We are on the line before target
  2195. (end-of-line)
  2196. (newline-and-indent))
  2197. (end-of-line) ; else - no splitting
  2198. (cond
  2199. ((and (looking-at "\n[ \t]*{$")
  2200. (save-excursion
  2201. (skip-chars-backward " \t")
  2202. (eq (preceding-char) ?\)))) ; Probably if () {} group
  2203. ; with an extra newline.
  2204. (forward-line 2)
  2205. (cperl-indent-line))
  2206. ((save-excursion ; In POD header
  2207. (forward-paragraph -1)
  2208. ;; (re-search-backward "\\(\\`\n?\\|\n\n\\)=head1\\b")
  2209. ;; We are after \n now, so look for the rest
  2210. (if (looking-at "\\(\\`\n?\\|\n\\)=\\sw+")
  2211. (progn
  2212. (setq cut (looking-at "\\(\\`\n?\\|\n\\)=cut\\>"))
  2213. (setq over (looking-at "\\(\\`\n?\\|\n\\)=over\\>"))
  2214. t)))
  2215. (if (and over
  2216. (progn
  2217. (forward-paragraph -1)
  2218. (forward-word 1)
  2219. (setq pos (point))
  2220. (setq cut (buffer-substring (point) (point-at-eol)))
  2221. (delete-char (- (point-at-eol) (point)))
  2222. (setq res (expand-abbrev))
  2223. (save-excursion
  2224. (goto-char pos)
  2225. (insert cut))
  2226. res))
  2227. nil
  2228. (cperl-ensure-newlines (if cut 2 4))
  2229. (forward-line 2)))
  2230. ((get-text-property (point) 'in-pod) ; In POD section
  2231. (cperl-ensure-newlines 4)
  2232. (forward-line 2))
  2233. ((looking-at "\n[ \t]*$") ; Next line is empty - use it.
  2234. (forward-line 1)
  2235. (cperl-indent-line))
  2236. (t
  2237. (newline-and-indent))))))
  2238. (defun cperl-electric-semi (arg)
  2239. "Insert character and correct line's indentation."
  2240. (interactive "P")
  2241. (if cperl-auto-newline
  2242. (cperl-electric-terminator arg)
  2243. (self-insert-command (prefix-numeric-value arg))
  2244. (if cperl-autoindent-on-semi
  2245. (cperl-indent-line))))
  2246. (defun cperl-electric-terminator (arg)
  2247. "Insert character and correct line's indentation."
  2248. (interactive "P")
  2249. (let ((end (point))
  2250. (auto (and cperl-auto-newline
  2251. (or (not (eq last-command-event ?:))
  2252. cperl-auto-newline-after-colon)))
  2253. insertpos)
  2254. (if (and ;;(not arg)
  2255. (eolp)
  2256. (not (save-excursion
  2257. (beginning-of-line)
  2258. (skip-chars-forward " \t")
  2259. (or
  2260. ;; Ignore in comment lines
  2261. (= (following-char) ?#)
  2262. ;; Colon is special only after a label
  2263. ;; So quickly rule out most other uses of colon
  2264. ;; and do no indentation for them.
  2265. (and (eq last-command-event ?:)
  2266. (save-excursion
  2267. (forward-word 1)
  2268. (skip-chars-forward " \t")
  2269. (and (< (point) end)
  2270. (progn (goto-char (- end 1))
  2271. (not (looking-at ":"))))))
  2272. (progn
  2273. (beginning-of-defun)
  2274. (let ((pps (parse-partial-sexp (point) end)))
  2275. (or (nth 3 pps) (nth 4 pps) (nth 5 pps))))))))
  2276. (progn
  2277. (self-insert-command (prefix-numeric-value arg))
  2278. ;;(forward-char -1)
  2279. (if auto (setq insertpos (point-marker)))
  2280. ;;(forward-char 1)
  2281. (cperl-indent-line)
  2282. (if auto
  2283. (progn
  2284. (newline)
  2285. (cperl-indent-line)))
  2286. (save-excursion
  2287. (if insertpos (goto-char (1- (marker-position insertpos)))
  2288. (forward-char -1))
  2289. (delete-char 1))))
  2290. (if insertpos
  2291. (save-excursion
  2292. (goto-char insertpos)
  2293. (self-insert-command (prefix-numeric-value arg)))
  2294. (self-insert-command (prefix-numeric-value arg)))))
  2295. (defun cperl-electric-backspace (arg)
  2296. "Backspace, or remove whitespace around the point inserted by an electric key.
  2297. Will untabify if `cperl-electric-backspace-untabify' is non-nil."
  2298. (interactive "p")
  2299. (if (and cperl-auto-newline
  2300. (memq last-command '(cperl-electric-semi
  2301. cperl-electric-terminator
  2302. cperl-electric-lbrace))
  2303. (memq (preceding-char) '(?\s ?\t ?\n)))
  2304. (let (p)
  2305. (if (eq last-command 'cperl-electric-lbrace)
  2306. (skip-chars-forward " \t\n"))
  2307. (setq p (point))
  2308. (skip-chars-backward " \t\n")
  2309. (delete-region (point) p))
  2310. (and (eq last-command 'cperl-electric-else)
  2311. ;; We are removing the whitespace *inside* cperl-electric-else
  2312. (setq this-command 'cperl-electric-else-really))
  2313. (if (and cperl-auto-newline
  2314. (eq last-command 'cperl-electric-else-really)
  2315. (memq (preceding-char) '(?\s ?\t ?\n)))
  2316. (let (p)
  2317. (skip-chars-forward " \t\n")
  2318. (setq p (point))
  2319. (skip-chars-backward " \t\n")
  2320. (delete-region (point) p))
  2321. (if cperl-electric-backspace-untabify
  2322. (backward-delete-char-untabify arg)
  2323. (delete-backward-char arg)))))
  2324. (put 'cperl-electric-backspace 'delete-selection 'supersede)
  2325. (defun cperl-inside-parens-p () ;; NOT USED????
  2326. (condition-case ()
  2327. (save-excursion
  2328. (save-restriction
  2329. (narrow-to-region (point)
  2330. (progn (beginning-of-defun) (point)))
  2331. (goto-char (point-max))
  2332. (= (char-after (or (scan-lists (point) -1 1) (point-min))) ?\()))
  2333. (error nil)))
  2334. (defun cperl-indent-command (&optional whole-exp)
  2335. "Indent current line as Perl code, or in some cases insert a tab character.
  2336. If `cperl-tab-always-indent' is non-nil (the default), always indent current
  2337. line. Otherwise, indent the current line only if point is at the left margin
  2338. or in the line's indentation; otherwise insert a tab.
  2339. A numeric argument, regardless of its value,
  2340. means indent rigidly all the lines of the expression starting after point
  2341. so that this line becomes properly indented.
  2342. The relative indentation among the lines of the expression are preserved."
  2343. (interactive "P")
  2344. (cperl-update-syntaxification (point) (point))
  2345. (if whole-exp
  2346. ;; If arg, always indent this line as Perl
  2347. ;; and shift remaining lines of expression the same amount.
  2348. (let ((shift-amt (cperl-indent-line))
  2349. beg end)
  2350. (save-excursion
  2351. (if cperl-tab-always-indent
  2352. (beginning-of-line))
  2353. (setq beg (point))
  2354. (forward-sexp 1)
  2355. (setq end (point))
  2356. (goto-char beg)
  2357. (forward-line 1)
  2358. (setq beg (point)))
  2359. (if (and shift-amt (> end beg))
  2360. (indent-code-rigidly beg end shift-amt "#")))
  2361. (if (and (not cperl-tab-always-indent)
  2362. (save-excursion
  2363. (skip-chars-backward " \t")
  2364. (not (bolp))))
  2365. (insert-tab)
  2366. (cperl-indent-line))))
  2367. (defun cperl-indent-line (&optional parse-data)
  2368. "Indent current line as Perl code.
  2369. Return the amount the indentation changed by."
  2370. (let ((case-fold-search nil)
  2371. (pos (- (point-max) (point)))
  2372. indent i beg shift-amt)
  2373. (setq indent (cperl-calculate-indent parse-data)
  2374. i indent)
  2375. (beginning-of-line)
  2376. (setq beg (point))
  2377. (cond ((or (eq indent nil) (eq indent t))
  2378. (setq indent (current-indentation) i nil))
  2379. ;;((eq indent t) ; Never?
  2380. ;; (setq indent (cperl-calculate-indent-within-comment)))
  2381. ;;((looking-at "[ \t]*#")
  2382. ;; (setq indent 0))
  2383. (t
  2384. (skip-chars-forward " \t")
  2385. (if (listp indent) (setq indent (car indent)))
  2386. (cond ((and (looking-at "[A-Za-z_][A-Za-z_0-9]*:[^:]")
  2387. (not (looking-at "[smy]:\\|tr:")))
  2388. (and (> indent 0)
  2389. (setq indent (max cperl-min-label-indent
  2390. (+ indent cperl-label-offset)))))
  2391. ((= (following-char) ?})
  2392. (setq indent (- indent cperl-indent-level)))
  2393. ((memq (following-char) '(?\) ?\])) ; To line up with opening paren.
  2394. (setq indent (+ indent cperl-close-paren-offset)))
  2395. ((= (following-char) ?{)
  2396. (setq indent (+ indent cperl-brace-offset))))))
  2397. (skip-chars-forward " \t")
  2398. (setq shift-amt (and i (- indent (current-column))))
  2399. (if (or (not shift-amt)
  2400. (zerop shift-amt))
  2401. (if (> (- (point-max) pos) (point))
  2402. (goto-char (- (point-max) pos)))
  2403. ;;;(delete-region beg (point))
  2404. ;;;(indent-to indent)
  2405. (cperl-make-indent indent)
  2406. ;; If initial point was within line's indentation,
  2407. ;; position after the indentation. Else stay at same point in text.
  2408. (if (> (- (point-max) pos) (point))
  2409. (goto-char (- (point-max) pos))))
  2410. shift-amt))
  2411. (defun cperl-after-label ()
  2412. ;; Returns true if the point is after label. Does not do save-excursion.
  2413. (and (eq (preceding-char) ?:)
  2414. (memq (char-syntax (char-after (- (point) 2)))
  2415. '(?w ?_))
  2416. (progn
  2417. (backward-sexp)
  2418. (looking-at "[a-zA-Z_][a-zA-Z0-9_]*:[^:]"))))
  2419. (defun cperl-get-state (&optional parse-start start-state)
  2420. ;; returns list (START STATE DEPTH PRESTART),
  2421. ;; START is a good place to start parsing, or equal to
  2422. ;; PARSE-START if preset,
  2423. ;; STATE is what is returned by `parse-partial-sexp'.
  2424. ;; DEPTH is true is we are immediately after end of block
  2425. ;; which contains START.
  2426. ;; PRESTART is the position basing on which START was found.
  2427. (save-excursion
  2428. (let ((start-point (point)) depth state start prestart)
  2429. (if (and parse-start
  2430. (<= parse-start start-point))
  2431. (goto-char parse-start)
  2432. (beginning-of-defun)
  2433. (setq start-state nil))
  2434. (setq prestart (point))
  2435. (if start-state nil
  2436. ;; Try to go out, if sub is not on the outermost level
  2437. (while (< (point) start-point)
  2438. (setq start (point) parse-start start depth nil
  2439. state (parse-partial-sexp start start-point -1))
  2440. (if (> (car state) -1) nil
  2441. ;; The current line could start like }}}, so the indentation
  2442. ;; corresponds to a different level than what we reached
  2443. (setq depth t)
  2444. (beginning-of-line 2))) ; Go to the next line.
  2445. (if start (goto-char start))) ; Not at the start of file
  2446. (setq start (point))
  2447. (or state (setq state (parse-partial-sexp start start-point -1 nil start-state)))
  2448. (list start state depth prestart))))
  2449. (defvar cperl-look-for-prop '((pod in-pod) (here-doc-delim here-doc-group)))
  2450. (defun cperl-beginning-of-property (p prop &optional lim)
  2451. "Given that P has a property PROP, find where the property starts.
  2452. Will not look before LIM."
  2453. ;;; XXXX What to do at point-max???
  2454. (or (previous-single-property-change (cperl-1+ p) prop lim)
  2455. (point-min))
  2456. ;;; (cond ((eq p (point-min))
  2457. ;;; p)
  2458. ;;; ((and lim (<= p lim))
  2459. ;;; p)
  2460. ;;; ((not (get-text-property (1- p) prop))
  2461. ;;; p)
  2462. ;;; (t (or (previous-single-property-change p look-prop lim)
  2463. ;;; (point-min))))
  2464. )
  2465. (defun cperl-sniff-for-indent (&optional parse-data) ; was parse-start
  2466. ;; the sniffer logic to understand what the current line MEANS.
  2467. (cperl-update-syntaxification (point) (point))
  2468. (let ((res (get-text-property (point) 'syntax-type)))
  2469. (save-excursion
  2470. (cond
  2471. ((and (memq res '(pod here-doc here-doc-delim format))
  2472. (not (get-text-property (point) 'indentable)))
  2473. (vector res))
  2474. ;; before start of POD - whitespace found since do not have 'pod!
  2475. ((looking-at "[ \t]*\n=")
  2476. (error "Spaces before POD section!"))
  2477. ((and (not cperl-indent-left-aligned-comments)
  2478. (looking-at "^#"))
  2479. [comment-special:at-beginning-of-line])
  2480. ((get-text-property (point) 'in-pod)
  2481. [in-pod])
  2482. (t
  2483. (beginning-of-line)
  2484. (let* ((indent-point (point))
  2485. (char-after-pos (save-excursion
  2486. (skip-chars-forward " \t")
  2487. (point)))
  2488. (char-after (char-after char-after-pos))
  2489. (pre-indent-point (point))
  2490. p prop look-prop is-block delim)
  2491. (save-excursion ; Know we are not in POD, find appropriate pos before
  2492. (cperl-backward-to-noncomment nil)
  2493. (setq p (max (point-min) (1- (point)))
  2494. prop (get-text-property p 'syntax-type)
  2495. look-prop (or (nth 1 (assoc prop cperl-look-for-prop))
  2496. 'syntax-type))
  2497. (if (memq prop '(pod here-doc format here-doc-delim))
  2498. (progn
  2499. (goto-char (cperl-beginning-of-property p look-prop))
  2500. (beginning-of-line)
  2501. (setq pre-indent-point (point)))))
  2502. (goto-char pre-indent-point) ; Orig line skipping preceding pod/etc
  2503. (let* ((case-fold-search nil)
  2504. (s-s (cperl-get-state (car parse-data) (nth 1 parse-data)))
  2505. (start (or (nth 2 parse-data) ; last complete sexp terminated
  2506. (nth 0 s-s))) ; Good place to start parsing
  2507. (state (nth 1 s-s))
  2508. (containing-sexp (car (cdr state)))
  2509. old-indent)
  2510. (if (and
  2511. ;;containing-sexp ;; We are buggy at toplevel :-(
  2512. parse-data)
  2513. (progn
  2514. (setcar parse-data pre-indent-point)
  2515. (setcar (cdr parse-data) state)
  2516. (or (nth 2 parse-data)
  2517. (setcar (cddr parse-data) start))
  2518. ;; Before this point: end of statement
  2519. (setq old-indent (nth 3 parse-data))))
  2520. (cond ((get-text-property (point) 'indentable)
  2521. ;; indent to "after" the surrounding open
  2522. ;; (same offset as `cperl-beautify-regexp-piece'),
  2523. ;; skip blanks if we do not close the expression.
  2524. (setq delim ; We do not close the expression
  2525. (get-text-property
  2526. (cperl-1+ char-after-pos) 'indentable)
  2527. p (1+ (cperl-beginning-of-property
  2528. (point) 'indentable))
  2529. is-block ; misused for: preceding line in REx
  2530. (save-excursion ; Find preceding line
  2531. (cperl-backward-to-noncomment p)
  2532. (beginning-of-line)
  2533. (if (<= (point) p)
  2534. (progn ; get indent from the first line
  2535. (goto-char p)
  2536. (skip-chars-forward " \t")
  2537. (if (memq (char-after (point))
  2538. (append "#\n" nil))
  2539. nil ; Can't use indentation of this line...
  2540. (point)))
  2541. (skip-chars-forward " \t")
  2542. (point)))
  2543. prop (parse-partial-sexp p char-after-pos))
  2544. (cond ((not delim) ; End the REx, ignore is-block
  2545. (vector 'indentable 'terminator p is-block))
  2546. (is-block ; Indent w.r.t. preceding line
  2547. (vector 'indentable 'cont-line char-after-pos
  2548. is-block char-after p))
  2549. (t ; No preceding line...
  2550. (vector 'indentable 'first-line p))))
  2551. ((get-text-property char-after-pos 'REx-part2)
  2552. (vector 'REx-part2 (point)))
  2553. ((nth 4 state)
  2554. [comment])
  2555. ((nth 3 state)
  2556. [string])
  2557. ;; XXXX Do we need to special-case this?
  2558. ((null containing-sexp)
  2559. ;; Line is at top level. May be data or function definition,
  2560. ;; or may be function argument declaration.
  2561. ;; Indent like the previous top level line
  2562. ;; unless that ends in a closeparen without semicolon,
  2563. ;; in which case this line is the first argument decl.
  2564. (skip-chars-forward " \t")
  2565. (cperl-backward-to-noncomment (or old-indent (point-min)))
  2566. (setq state
  2567. (or (bobp)
  2568. (eq (point) old-indent) ; old-indent was at comment
  2569. (eq (preceding-char) ?\;)
  2570. ;; Had ?\) too
  2571. (and (eq (preceding-char) ?\})
  2572. (cperl-after-block-and-statement-beg
  2573. (point-min))) ; Was start - too close
  2574. (memq char-after (append ")]}" nil))
  2575. (and (eq (preceding-char) ?\:) ; label
  2576. (progn
  2577. (forward-sexp -1)
  2578. (skip-chars-backward " \t")
  2579. (looking-at "[ \t]*[a-zA-Z_][a-zA-Z_0-9]*[ \t]*:")))
  2580. (get-text-property (point) 'first-format-line)))
  2581. ;; Look at previous line that's at column 0
  2582. ;; to determine whether we are in top-level decls
  2583. ;; or function's arg decls. Set basic-indent accordingly.
  2584. ;; Now add a little if this is a continuation line.
  2585. (and state
  2586. parse-data
  2587. (not (eq char-after ?\C-j))
  2588. (setcdr (cddr parse-data)
  2589. (list pre-indent-point)))
  2590. (vector 'toplevel start char-after state (nth 2 s-s)))
  2591. ((not
  2592. (or (setq is-block
  2593. (and (setq delim (= (char-after containing-sexp) ?{))
  2594. (save-excursion ; Is it a hash?
  2595. (goto-char containing-sexp)
  2596. (cperl-block-p))))
  2597. cperl-indent-parens-as-block))
  2598. ;; group is an expression, not a block:
  2599. ;; indent to just after the surrounding open parens,
  2600. ;; skip blanks if we do not close the expression.
  2601. (goto-char (1+ containing-sexp))
  2602. (or (memq char-after
  2603. (append (if delim "}" ")]}") nil))
  2604. (looking-at "[ \t]*\\(#\\|$\\)")
  2605. (skip-chars-forward " \t"))
  2606. (setq old-indent (point)) ; delim=is-brace
  2607. (vector 'in-parens char-after (point) delim containing-sexp))
  2608. (t
  2609. ;; Statement level. Is it a continuation or a new statement?
  2610. ;; Find previous non-comment character.
  2611. (goto-char pre-indent-point) ; Skip one level of POD/etc
  2612. (cperl-backward-to-noncomment containing-sexp)
  2613. ;; Back up over label lines, since they don't
  2614. ;; affect whether our line is a continuation.
  2615. ;; (Had \, too)
  2616. (while;;(or (eq (preceding-char) ?\,)
  2617. (and (eq (preceding-char) ?:)
  2618. (or;;(eq (char-after (- (point) 2)) ?\') ; ????
  2619. (memq (char-syntax (char-after (- (point) 2)))
  2620. '(?w ?_))))
  2621. ;;)
  2622. ;; This is always FALSE?
  2623. (if (eq (preceding-char) ?\,)
  2624. ;; Will go to beginning of line, essentially.
  2625. ;; Will ignore embedded sexpr XXXX.
  2626. (cperl-backward-to-start-of-continued-exp containing-sexp))
  2627. (beginning-of-line)
  2628. (cperl-backward-to-noncomment containing-sexp))
  2629. ;; Now we get non-label preceding the indent point
  2630. (if (not (or (eq (1- (point)) containing-sexp)
  2631. (memq (preceding-char)
  2632. (append (if is-block " ;{" " ,;{") '(nil)))
  2633. (and (eq (preceding-char) ?\})
  2634. (cperl-after-block-and-statement-beg
  2635. containing-sexp))
  2636. (get-text-property (point) 'first-format-line)))
  2637. ;; This line is continuation of preceding line's statement;
  2638. ;; indent `cperl-continued-statement-offset' more than the
  2639. ;; previous line of the statement.
  2640. ;;
  2641. ;; There might be a label on this line, just
  2642. ;; consider it bad style and ignore it.
  2643. (progn
  2644. (cperl-backward-to-start-of-continued-exp containing-sexp)
  2645. (vector 'continuation (point) char-after is-block delim))
  2646. ;; This line starts a new statement.
  2647. ;; Position following last unclosed open brace
  2648. (goto-char containing-sexp)
  2649. ;; Is line first statement after an open-brace?
  2650. (or
  2651. ;; If no, find that first statement and indent like
  2652. ;; it. If the first statement begins with label, do
  2653. ;; not believe when the indentation of the label is too
  2654. ;; small.
  2655. (save-excursion
  2656. (forward-char 1)
  2657. (let ((colon-line-end 0))
  2658. (while
  2659. (progn (skip-chars-forward " \t\n")
  2660. ;; s: foo : bar :x is NOT label
  2661. (and (looking-at "#\\|\\([a-zA-Z0-9_$]+\\):[^:]\\|=[a-zA-Z]")
  2662. (not (looking-at "[sym]:\\|tr:"))))
  2663. ;; Skip over comments and labels following openbrace.
  2664. (cond ((= (following-char) ?\#)
  2665. (forward-line 1))
  2666. ((= (following-char) ?\=)
  2667. (goto-char
  2668. (or (next-single-property-change (point) 'in-pod)
  2669. (point-max)))) ; do not loop if no syntaxification
  2670. ;; label:
  2671. (t
  2672. (setq colon-line-end (point-at-eol))
  2673. (search-forward ":"))))
  2674. ;; We are at beginning of code (NOT label or comment)
  2675. ;; First, the following code counts
  2676. ;; if it is before the line we want to indent.
  2677. (and (< (point) indent-point)
  2678. (vector 'have-prev-sibling (point) colon-line-end
  2679. containing-sexp))))
  2680. (progn
  2681. ;; If no previous statement,
  2682. ;; indent it relative to line brace is on.
  2683. ;; For open-braces not the first thing in a line,
  2684. ;; add in cperl-brace-imaginary-offset.
  2685. ;; If first thing on a line: ?????
  2686. ;; Move back over whitespace before the openbrace.
  2687. (setq ; brace first thing on a line
  2688. old-indent (progn (skip-chars-backward " \t") (bolp)))
  2689. ;; Should we indent w.r.t. earlier than start?
  2690. ;; Move to start of control group, possibly on a different line
  2691. (or cperl-indent-wrt-brace
  2692. (cperl-backward-to-noncomment (point-min)))
  2693. ;; If the openbrace is preceded by a parenthesized exp,
  2694. ;; move to the beginning of that;
  2695. (if (eq (preceding-char) ?\))
  2696. (progn
  2697. (forward-sexp -1)
  2698. (cperl-backward-to-noncomment (point-min))))
  2699. ;; In the case it starts a subroutine, indent with
  2700. ;; respect to `sub', not with respect to the
  2701. ;; first thing on the line, say in the case of
  2702. ;; anonymous sub in a hash.
  2703. (if (and;; Is it a sub in group starting on this line?
  2704. (cond ((get-text-property (point) 'attrib-group)
  2705. (goto-char (cperl-beginning-of-property
  2706. (point) 'attrib-group)))
  2707. ((eq (preceding-char) ?b)
  2708. (forward-sexp -1)
  2709. (looking-at "sub\\>")))
  2710. (setq p (nth 1 ; start of innermost containing list
  2711. (parse-partial-sexp
  2712. (point-at-bol)
  2713. (point)))))
  2714. (progn
  2715. (goto-char (1+ p)) ; enclosing block on the same line
  2716. (skip-chars-forward " \t")
  2717. (vector 'code-start-in-block containing-sexp char-after
  2718. (and delim (not is-block)) ; is a HASH
  2719. old-indent ; brace first thing on a line
  2720. t (point) ; have something before...
  2721. )
  2722. ;;(current-column)
  2723. )
  2724. ;; Get initial indentation of the line we are on.
  2725. ;; If line starts with label, calculate label indentation
  2726. (vector 'code-start-in-block containing-sexp char-after
  2727. (and delim (not is-block)) ; is a HASH
  2728. old-indent ; brace first thing on a line
  2729. nil (point))))))))))))))) ; nothing interesting before
  2730. (defvar cperl-indent-rules-alist
  2731. '((pod nil) ; via `syntax-type' property
  2732. (here-doc nil) ; via `syntax-type' property
  2733. (here-doc-delim nil) ; via `syntax-type' property
  2734. (format nil) ; via `syntax-type' property
  2735. (in-pod nil) ; via `in-pod' property
  2736. (comment-special:at-beginning-of-line nil)
  2737. (string t)
  2738. (comment nil))
  2739. "Alist of indentation rules for CPerl mode.
  2740. The values mean:
  2741. nil: do not indent;
  2742. number: add this amount of indentation.")
  2743. (defun cperl-calculate-indent (&optional parse-data) ; was parse-start
  2744. "Return appropriate indentation for current line as Perl code.
  2745. In usual case returns an integer: the column to indent to.
  2746. Returns nil if line starts inside a string, t if in a comment.
  2747. Will not correct the indentation for labels, but will correct it for braces
  2748. and closing parentheses and brackets."
  2749. ;; This code is still a broken architecture: in some cases we need to
  2750. ;; compensate for some modifications which `cperl-indent-line' will add later
  2751. (save-excursion
  2752. (let ((i (cperl-sniff-for-indent parse-data)) what p)
  2753. (cond
  2754. ;;((or (null i) (eq i t) (numberp i))
  2755. ;; i)
  2756. ((vectorp i)
  2757. (setq what (assoc (elt i 0) cperl-indent-rules-alist))
  2758. (cond
  2759. (what (cadr what)) ; Load from table
  2760. ;;
  2761. ;; Indenters for regular expressions with //x and qw()
  2762. ;;
  2763. ((eq 'REx-part2 (elt i 0)) ;; [self start] start of /REP in s//REP/x
  2764. (goto-char (elt i 1))
  2765. (condition-case nil ; Use indentation of the 1st part
  2766. (forward-sexp -1))
  2767. (current-column))
  2768. ((eq 'indentable (elt i 0)) ; Indenter for REGEXP qw() etc
  2769. (cond ;;; [indentable terminator start-pos is-block]
  2770. ((eq 'terminator (elt i 1)) ; Lone terminator of "indentable string"
  2771. (goto-char (elt i 2)) ; After opening parens
  2772. (1- (current-column)))
  2773. ((eq 'first-line (elt i 1)); [indentable first-line start-pos]
  2774. (goto-char (elt i 2))
  2775. (+ (or cperl-regexp-indent-step cperl-indent-level)
  2776. -1
  2777. (current-column)))
  2778. ((eq 'cont-line (elt i 1)); [indentable cont-line pos prev-pos first-char start-pos]
  2779. ;; Indent as the level after closing parens
  2780. (goto-char (elt i 2)) ; indent line
  2781. (skip-chars-forward " \t)") ; Skip closing parens
  2782. (setq p (point))
  2783. (goto-char (elt i 3)) ; previous line
  2784. (skip-chars-forward " \t)") ; Skip closing parens
  2785. ;; Number of parens in between:
  2786. (setq p (nth 0 (parse-partial-sexp (point) p))
  2787. what (elt i 4)) ; First char on current line
  2788. (goto-char (elt i 3)) ; previous line
  2789. (+ (* p (or cperl-regexp-indent-step cperl-indent-level))
  2790. (cond ((eq what ?\) )
  2791. (- cperl-close-paren-offset)) ; compensate
  2792. ((eq what ?\| )
  2793. (- (or cperl-regexp-indent-step cperl-indent-level)))
  2794. (t 0))
  2795. (if (eq (following-char) ?\| )
  2796. (or cperl-regexp-indent-step cperl-indent-level)
  2797. 0)
  2798. (current-column)))
  2799. (t
  2800. (error "Unrecognized value of indent: %s" i))))
  2801. ;;
  2802. ;; Indenter for stuff at toplevel
  2803. ;;
  2804. ((eq 'toplevel (elt i 0)) ;; [toplevel start char-after state immed-after-block]
  2805. (+ (save-excursion ; To beg-of-defun, or end of last sexp
  2806. (goto-char (elt i 1)) ; start = Good place to start parsing
  2807. (- (current-indentation) ;
  2808. (if (elt i 4) cperl-indent-level 0))) ; immed-after-block
  2809. (if (eq (elt i 2) ?{) cperl-continued-brace-offset 0) ; char-after
  2810. ;; Look at previous line that's at column 0
  2811. ;; to determine whether we are in top-level decls
  2812. ;; or function's arg decls. Set basic-indent accordingly.
  2813. ;; Now add a little if this is a continuation line.
  2814. (if (elt i 3) ; state (XXX What is the semantic???)
  2815. 0
  2816. cperl-continued-statement-offset)))
  2817. ;;
  2818. ;; Indenter for stuff in "parentheses" (or brackets, braces-as-hash)
  2819. ;;
  2820. ((eq 'in-parens (elt i 0))
  2821. ;; in-parens char-after old-indent-point is-brace containing-sexp
  2822. ;; group is an expression, not a block:
  2823. ;; indent to just after the surrounding open parens,
  2824. ;; skip blanks if we do not close the expression.
  2825. (+ (progn
  2826. (goto-char (elt i 2)) ; old-indent-point
  2827. (current-column))
  2828. (if (and (elt i 3) ; is-brace
  2829. (eq (elt i 1) ?\})) ; char-after
  2830. ;; Correct indentation of trailing ?\}
  2831. (+ cperl-indent-level cperl-close-paren-offset)
  2832. 0)))
  2833. ;;
  2834. ;; Indenter for continuation lines
  2835. ;;
  2836. ((eq 'continuation (elt i 0))
  2837. ;; [continuation statement-start char-after is-block is-brace]
  2838. (goto-char (elt i 1)) ; statement-start
  2839. (+ (if (memq (elt i 2) (append "}])" nil)) ; char-after
  2840. 0 ; Closing parenth
  2841. cperl-continued-statement-offset)
  2842. (if (or (elt i 3) ; is-block
  2843. (not (elt i 4)) ; is-brace
  2844. (not (eq (elt i 2) ?\}))) ; char-after
  2845. 0
  2846. ;; Now it is a hash reference
  2847. (+ cperl-indent-level cperl-close-paren-offset))
  2848. ;; Labels do not take :: ...
  2849. (if (looking-at "\\(\\w\\|_\\)+[ \t]*:")
  2850. (if (> (current-indentation) cperl-min-label-indent)
  2851. (- (current-indentation) cperl-label-offset)
  2852. ;; Do not move `parse-data', this should
  2853. ;; be quick anyway (this comment comes
  2854. ;; from different location):
  2855. (cperl-calculate-indent))
  2856. (current-column))
  2857. (if (eq (elt i 2) ?\{) ; char-after
  2858. cperl-continued-brace-offset 0)))
  2859. ;;
  2860. ;; Indenter for lines in a block which are not leading lines
  2861. ;;
  2862. ((eq 'have-prev-sibling (elt i 0))
  2863. ;; [have-prev-sibling sibling-beg colon-line-end block-start]
  2864. (goto-char (elt i 1)) ; sibling-beg
  2865. (if (> (elt i 2) (point)) ; colon-line-end; have label before point
  2866. (if (> (current-indentation)
  2867. cperl-min-label-indent)
  2868. (- (current-indentation) cperl-label-offset)
  2869. ;; Do not believe: `max' was involved in calculation of indent
  2870. (+ cperl-indent-level
  2871. (save-excursion
  2872. (goto-char (elt i 3)) ; block-start
  2873. (current-indentation))))
  2874. (current-column)))
  2875. ;;
  2876. ;; Indenter for the first line in a block
  2877. ;;
  2878. ((eq 'code-start-in-block (elt i 0))
  2879. ;;[code-start-in-block before-brace char-after
  2880. ;; is-a-HASH-ref brace-is-first-thing-on-a-line
  2881. ;; group-starts-before-start-of-sub start-of-control-group]
  2882. (goto-char (elt i 1))
  2883. ;; For open brace in column zero, don't let statement
  2884. ;; start there too. If cperl-indent-level=0,
  2885. ;; use cperl-brace-offset + cperl-continued-statement-offset instead.
  2886. (+ (if (and (bolp) (zerop cperl-indent-level))
  2887. (+ cperl-brace-offset cperl-continued-statement-offset)
  2888. cperl-indent-level)
  2889. (if (and (elt i 3) ; is-a-HASH-ref
  2890. (eq (elt i 2) ?\})) ; char-after: End of a hash reference
  2891. (+ cperl-indent-level cperl-close-paren-offset)
  2892. 0)
  2893. ;; Unless openbrace is the first nonwhite thing on the line,
  2894. ;; add the cperl-brace-imaginary-offset.
  2895. (if (elt i 4) 0 ; brace-is-first-thing-on-a-line
  2896. cperl-brace-imaginary-offset)
  2897. (progn
  2898. (goto-char (elt i 6)) ; start-of-control-group
  2899. (if (elt i 5) ; group-starts-before-start-of-sub
  2900. (current-column)
  2901. ;; Get initial indentation of the line we are on.
  2902. ;; If line starts with label, calculate label indentation
  2903. (if (save-excursion
  2904. (beginning-of-line)
  2905. (looking-at "[ \t]*[a-zA-Z_][a-zA-Z_0-9]*:[^:]"))
  2906. (if (> (current-indentation) cperl-min-label-indent)
  2907. (- (current-indentation) cperl-label-offset)
  2908. ;; Do not move `parse-data', this should
  2909. ;; be quick anyway:
  2910. (cperl-calculate-indent))
  2911. (current-indentation))))))
  2912. (t
  2913. (error "Unrecognized value of indent: %s" i))))
  2914. (t
  2915. (error "Got strange value of indent: %s" i))))))
  2916. (defun cperl-calculate-indent-within-comment ()
  2917. "Return the indentation amount for line, assuming that
  2918. the current line is to be regarded as part of a block comment."
  2919. (let (end star-start)
  2920. (save-excursion
  2921. (beginning-of-line)
  2922. (skip-chars-forward " \t")
  2923. (setq end (point))
  2924. (and (= (following-char) ?#)
  2925. (forward-line -1)
  2926. (cperl-to-comment-or-eol)
  2927. (setq end (point)))
  2928. (goto-char end)
  2929. (current-column))))
  2930. (defun cperl-to-comment-or-eol ()
  2931. "Go to position before comment on the current line, or to end of line.
  2932. Returns true if comment is found. In POD will not move the point."
  2933. ;; If the line is inside other syntax groups (qq-style strings, HERE-docs)
  2934. ;; then looks for literal # or end-of-line.
  2935. (let (state stop-in cpoint (lim (point-at-eol)) pr e)
  2936. (or cperl-font-locking
  2937. (cperl-update-syntaxification lim lim))
  2938. (beginning-of-line)
  2939. (if (setq pr (get-text-property (point) 'syntax-type))
  2940. (setq e (next-single-property-change (point) 'syntax-type nil (point-max))))
  2941. (if (or (eq pr 'pod)
  2942. (if (or (not e) (> e lim)) ; deep inside a group
  2943. (re-search-forward "\\=[ \t]*\\(#\\|$\\)" lim t)))
  2944. (if (eq (preceding-char) ?\#) (progn (backward-char 1) t))
  2945. ;; Else - need to do it the hard way
  2946. (and (and e (<= e lim))
  2947. (goto-char e))
  2948. (while (not stop-in)
  2949. (setq state (parse-partial-sexp (point) lim nil nil nil t))
  2950. ; stop at comment
  2951. ;; If fails (beginning-of-line inside sexp), then contains not-comment
  2952. (if (nth 4 state) ; After `#';
  2953. ; (nth 2 state) can be
  2954. ; beginning of m,s,qq and so
  2955. ; on
  2956. (if (nth 2 state)
  2957. (progn
  2958. (setq cpoint (point))
  2959. (goto-char (nth 2 state))
  2960. (cond
  2961. ((looking-at "\\(s\\|tr\\)\\>")
  2962. (or (re-search-forward
  2963. "\\=\\w+[ \t]*#\\([^\n\\\\#]\\|\\\\[\\\\#]\\)*#\\([^\n\\\\#]\\|\\\\[\\\\#]\\)*"
  2964. lim 'move)
  2965. (setq stop-in t)))
  2966. ((looking-at "\\(m\\|q\\([qxwr]\\)?\\)\\>")
  2967. (or (re-search-forward
  2968. "\\=\\w+[ \t]*#\\([^\n\\\\#]\\|\\\\[\\\\#]\\)*#"
  2969. lim 'move)
  2970. (setq stop-in t)))
  2971. (t ; It was fair comment
  2972. (setq stop-in t) ; Finish
  2973. (goto-char (1- cpoint)))))
  2974. (setq stop-in t) ; Finish
  2975. (forward-char -1))
  2976. (setq stop-in t))) ; Finish
  2977. (nth 4 state))))
  2978. (defsubst cperl-modify-syntax-type (at how)
  2979. (if (< at (point-max))
  2980. (progn
  2981. (put-text-property at (1+ at) 'syntax-table how)
  2982. (put-text-property at (1+ at) 'rear-nonsticky '(syntax-table)))))
  2983. (defun cperl-protect-defun-start (s e)
  2984. ;; C code looks for "^\\s(" to skip comment backward in "hard" situations
  2985. (save-excursion
  2986. (goto-char s)
  2987. (while (re-search-forward "^\\s(" e 'to-end)
  2988. (put-text-property (1- (point)) (point) 'syntax-table cperl-st-punct))))
  2989. (defun cperl-commentify (bb e string &optional noface)
  2990. (if cperl-use-syntax-table-text-property
  2991. (if (eq noface 'n) ; Only immediate
  2992. nil
  2993. ;; We suppose that e is _after_ the end of construction, as after eol.
  2994. (setq string (if string cperl-st-sfence cperl-st-cfence))
  2995. (if (> bb (- e 2))
  2996. ;; one-char string/comment?!
  2997. (cperl-modify-syntax-type bb cperl-st-punct)
  2998. (cperl-modify-syntax-type bb string)
  2999. (cperl-modify-syntax-type (1- e) string))
  3000. (if (and (eq string cperl-st-sfence) (> (- e 2) bb))
  3001. (put-text-property (1+ bb) (1- e)
  3002. 'syntax-table cperl-string-syntax-table))
  3003. (cperl-protect-defun-start bb e))
  3004. ;; Fontify
  3005. (or noface
  3006. (not cperl-pod-here-fontify)
  3007. (put-text-property bb e 'face (if string 'font-lock-string-face
  3008. 'font-lock-comment-face)))))
  3009. (defvar cperl-starters '(( ?\( . ?\) )
  3010. ( ?\[ . ?\] )
  3011. ( ?\{ . ?\} )
  3012. ( ?\< . ?\> )))
  3013. (defun cperl-cached-syntax-table (st)
  3014. "Get a syntax table cached in ST, or create and cache into ST a syntax table.
  3015. All the entries of the syntax table are \".\", except for a backslash, which
  3016. is quoting."
  3017. (if (car-safe st)
  3018. (car st)
  3019. (setcar st (make-syntax-table))
  3020. (setq st (car st))
  3021. (let ((i 0))
  3022. (while (< i 256)
  3023. (modify-syntax-entry i "." st)
  3024. (setq i (1+ i))))
  3025. (modify-syntax-entry ?\\ "\\" st)
  3026. st))
  3027. (defun cperl-forward-re (lim end is-2arg st-l err-l argument
  3028. &optional ostart oend)
  3029. "Find the end of a regular expression or a stringish construct (q[] etc).
  3030. The point should be before the starting delimiter.
  3031. Goes to LIM if none is found. If IS-2ARG is non-nil, assumes that it
  3032. is s/// or tr/// like expression. If END is nil, generates an error
  3033. message if needed. If SET-ST is non-nil, will use (or generate) a
  3034. cached syntax table in ST-L. If ERR-L is non-nil, will store the
  3035. error message in its CAR (unless it already contains some error
  3036. message). ARGUMENT should be the name of the construct (used in error
  3037. messages). OSTART, OEND may be set in recursive calls when processing
  3038. the second argument of 2ARG construct.
  3039. Works *before* syntax recognition is done. In IS-2ARG situation may
  3040. modify syntax-type text property if the situation is too hard."
  3041. (let (b starter ender st i i2 go-forward reset-st set-st)
  3042. (skip-chars-forward " \t")
  3043. ;; ender means matching-char matcher.
  3044. (setq b (point)
  3045. starter (if (eobp) 0 (char-after b))
  3046. ender (cdr (assoc starter cperl-starters)))
  3047. ;; What if starter == ?\\ ????
  3048. (setq st (cperl-cached-syntax-table st-l))
  3049. (setq set-st t)
  3050. ;; Whether we have an intermediate point
  3051. (setq i nil)
  3052. ;; Prepare the syntax table:
  3053. (if (not ender) ; m/blah/, s/x//, s/x/y/
  3054. (modify-syntax-entry starter "$" st)
  3055. (modify-syntax-entry starter (concat "(" (list ender)) st)
  3056. (modify-syntax-entry ender (concat ")" (list starter)) st))
  3057. (condition-case bb
  3058. (progn
  3059. ;; We use `$' syntax class to find matching stuff, but $$
  3060. ;; is recognized the same as $, so we need to check this manually.
  3061. (if (and (eq starter (char-after (cperl-1+ b)))
  3062. (not ender))
  3063. ;; $ has TeXish matching rules, so $$ equiv $...
  3064. (forward-char 2)
  3065. (setq reset-st (syntax-table))
  3066. (set-syntax-table st)
  3067. (forward-sexp 1)
  3068. (if (<= (point) (1+ b))
  3069. (error "Unfinished regular expression"))
  3070. (set-syntax-table reset-st)
  3071. (setq reset-st nil)
  3072. ;; Now the problem is with m;blah;;
  3073. (and (not ender)
  3074. (eq (preceding-char)
  3075. (char-after (- (point) 2)))
  3076. (save-excursion
  3077. (forward-char -2)
  3078. (= 0 (% (skip-chars-backward "\\\\") 2)))
  3079. (forward-char -1)))
  3080. ;; Now we are after the first part.
  3081. (and is-2arg ; Have trailing part
  3082. (not ender)
  3083. (eq (following-char) starter) ; Empty trailing part
  3084. (progn
  3085. (or (eq (char-syntax (following-char)) ?.)
  3086. ;; Make trailing letter into punctuation
  3087. (cperl-modify-syntax-type (point) cperl-st-punct))
  3088. (setq is-2arg nil go-forward t))) ; Ignore the tail
  3089. (if is-2arg ; Not number => have second part
  3090. (progn
  3091. (setq i (point) i2 i)
  3092. (if ender
  3093. (if (memq (following-char) '(?\s ?\t ?\n ?\f))
  3094. (progn
  3095. (if (looking-at "[ \t\n\f]+\\(#[^\n]*\n[ \t\n\f]*\\)+")
  3096. (goto-char (match-end 0))
  3097. (skip-chars-forward " \t\n\f"))
  3098. (setq i2 (point))))
  3099. (forward-char -1))
  3100. (modify-syntax-entry starter (if (eq starter ?\\) "\\" ".") st)
  3101. (if ender (modify-syntax-entry ender "." st))
  3102. (setq set-st nil)
  3103. (setq ender (cperl-forward-re lim end nil st-l err-l
  3104. argument starter ender)
  3105. ender (nth 2 ender)))))
  3106. (error (goto-char lim)
  3107. (setq set-st nil)
  3108. (if reset-st
  3109. (set-syntax-table reset-st))
  3110. (or end
  3111. (and cperl-brace-recursing
  3112. (or (eq ostart ?\{)
  3113. (eq starter ?\{)))
  3114. (message
  3115. "End of `%s%s%c ... %c' string/RE not found: %s"
  3116. argument
  3117. (if ostart (format "%c ... %c" ostart (or oend ostart)) "")
  3118. starter (or ender starter) bb)
  3119. (or (car err-l) (setcar err-l b)))))
  3120. (if set-st
  3121. (progn
  3122. (modify-syntax-entry starter (if (eq starter ?\\) "\\" ".") st)
  3123. (if ender (modify-syntax-entry ender "." st))))
  3124. ;; i: have 2 args, after end of the first arg
  3125. ;; i2: start of the second arg, if any (before delim if `ender').
  3126. ;; ender: the last arg bounded by parens-like chars, the second one of them
  3127. ;; starter: the starting delimiter of the first arg
  3128. ;; go-forward: has 2 args, and the second part is empty
  3129. (list i i2 ender starter go-forward)))
  3130. (defun cperl-forward-group-in-re (&optional st-l)
  3131. "Find the end of a group in a REx.
  3132. Return the error message (if any). Does not work if delimiter is `)'.
  3133. Works before syntax recognition is done."
  3134. ;; Works *before* syntax recognition is done
  3135. (or st-l (setq st-l (list nil))) ; Avoid overwriting '()
  3136. (let (st b reset-st)
  3137. (condition-case b
  3138. (progn
  3139. (setq st (cperl-cached-syntax-table st-l))
  3140. (modify-syntax-entry ?\( "()" st)
  3141. (modify-syntax-entry ?\) ")(" st)
  3142. (setq reset-st (syntax-table))
  3143. (set-syntax-table st)
  3144. (forward-sexp 1))
  3145. (error (message
  3146. "cperl-forward-group-in-re: error %s" b)))
  3147. ;; now restore the initial state
  3148. (if st
  3149. (progn
  3150. (modify-syntax-entry ?\( "." st)
  3151. (modify-syntax-entry ?\) "." st)))
  3152. (if reset-st
  3153. (set-syntax-table reset-st))
  3154. b))
  3155. (defvar font-lock-string-face)
  3156. ;;(defvar font-lock-reference-face)
  3157. (defvar font-lock-constant-face)
  3158. (defsubst cperl-postpone-fontification (b e type val &optional now)
  3159. ;; Do after syntactic fontification?
  3160. (if cperl-syntaxify-by-font-lock
  3161. (or now (put-text-property b e 'cperl-postpone (cons type val)))
  3162. (put-text-property b e type val)))
  3163. ;;; Here is how the global structures (those which cannot be
  3164. ;;; recognized locally) are marked:
  3165. ;; a) PODs:
  3166. ;; Start-to-end is marked `in-pod' ==> t
  3167. ;; Each non-literal part is marked `syntax-type' ==> `pod'
  3168. ;; Each literal part is marked `syntax-type' ==> `in-pod'
  3169. ;; b) HEREs:
  3170. ;; Start-to-end is marked `here-doc-group' ==> t
  3171. ;; The body is marked `syntax-type' ==> `here-doc'
  3172. ;; The delimiter is marked `syntax-type' ==> `here-doc-delim'
  3173. ;; c) FORMATs:
  3174. ;; First line (to =) marked `first-format-line' ==> t
  3175. ;; After-this--to-end is marked `syntax-type' ==> `format'
  3176. ;; d) 'Q'uoted string:
  3177. ;; part between markers inclusive is marked `syntax-type' ==> `string'
  3178. ;; part between `q' and the first marker is marked `syntax-type' ==> `prestring'
  3179. ;; second part of s///e is marked `syntax-type' ==> `multiline'
  3180. ;; e) Attributes of subroutines: `attrib-group' ==> t
  3181. ;; (or 0 if declaration); up to `{' or ';': `syntax-type' => `sub-decl'.
  3182. ;; f) Multiline my/our declaration lists etc: `syntax-type' => `multiline'
  3183. ;;; In addition, some parts of RExes may be marked as `REx-interpolated'
  3184. ;;; (value: 0 in //o, 1 if "interpolated variable" is whole-REx, t otherwise).
  3185. (defun cperl-unwind-to-safe (before &optional end)
  3186. ;; if BEFORE, go to the previous start-of-line on each step of unwinding
  3187. (let ((pos (point)) opos)
  3188. (while (and pos (progn
  3189. (beginning-of-line)
  3190. (get-text-property (setq pos (point)) 'syntax-type)))
  3191. (setq opos pos
  3192. pos (cperl-beginning-of-property pos 'syntax-type))
  3193. (if (eq pos (point-min))
  3194. (setq pos nil))
  3195. (if pos
  3196. (if before
  3197. (progn
  3198. (goto-char (cperl-1- pos))
  3199. (beginning-of-line)
  3200. (setq pos (point)))
  3201. (goto-char (setq pos (cperl-1- pos))))
  3202. ;; Up to the start
  3203. (goto-char (point-min))))
  3204. ;; Skip empty lines
  3205. (and (looking-at "\n*=")
  3206. (/= 0 (skip-chars-backward "\n"))
  3207. (forward-char))
  3208. (setq pos (point))
  3209. (if end
  3210. ;; Do the same for end, going small steps
  3211. (save-excursion
  3212. (while (and end (< end (point-max))
  3213. (get-text-property end 'syntax-type))
  3214. (setq pos end
  3215. end (next-single-property-change end 'syntax-type nil (point-max)))
  3216. (if end (progn (goto-char end)
  3217. (or (bolp) (forward-line 1))
  3218. (setq end (point)))))
  3219. (or end pos)))))
  3220. ;;; These are needed for byte-compile (at least with v19)
  3221. (defvar cperl-nonoverridable-face)
  3222. (defvar font-lock-variable-name-face)
  3223. (defvar font-lock-function-name-face)
  3224. (defvar font-lock-keyword-face)
  3225. (defvar font-lock-builtin-face)
  3226. (defvar font-lock-type-face)
  3227. (defvar font-lock-comment-face)
  3228. (defvar font-lock-warning-face)
  3229. (defun cperl-find-sub-attrs (&optional st-l b-fname e-fname pos)
  3230. "Syntactically mark (and fontify) attributes of a subroutine.
  3231. Should be called with the point before leading colon of an attribute."
  3232. ;; Works *before* syntax recognition is done
  3233. (or st-l (setq st-l (list nil))) ; Avoid overwriting '()
  3234. (let (st b p reset-st after-first (start (point)) start1 end1)
  3235. (condition-case b
  3236. (while (looking-at
  3237. (concat
  3238. "\\(" ; 1=optional? colon
  3239. ":" cperl-maybe-white-and-comment-rex ; 2=whitespace/comment?
  3240. "\\)"
  3241. (if after-first "?" "")
  3242. ;; No space between name and paren allowed...
  3243. "\\(\\sw+\\)" ; 3=name
  3244. "\\((\\)?")) ; 4=optional paren
  3245. (and (match-beginning 1)
  3246. (cperl-postpone-fontification
  3247. (match-beginning 0) (cperl-1+ (match-beginning 0))
  3248. 'face font-lock-constant-face))
  3249. (setq start1 (match-beginning 3) end1 (match-end 3))
  3250. (cperl-postpone-fontification start1 end1
  3251. 'face font-lock-constant-face)
  3252. (goto-char end1) ; end or before `('
  3253. (if (match-end 4) ; Have attribute arguments...
  3254. (progn
  3255. (if st nil
  3256. (setq st (cperl-cached-syntax-table st-l))
  3257. (modify-syntax-entry ?\( "()" st)
  3258. (modify-syntax-entry ?\) ")(" st))
  3259. (setq reset-st (syntax-table) p (point))
  3260. (set-syntax-table st)
  3261. (forward-sexp 1)
  3262. (set-syntax-table reset-st)
  3263. (setq reset-st nil)
  3264. (cperl-commentify p (point) t))) ; mark as string
  3265. (forward-comment (buffer-size))
  3266. (setq after-first t))
  3267. (error (message
  3268. "L%d: attribute `%s': %s"
  3269. (count-lines (point-min) (point))
  3270. (and start1 end1 (buffer-substring start1 end1)) b)
  3271. (setq start nil)))
  3272. (and start
  3273. (progn
  3274. (put-text-property start (point)
  3275. 'attrib-group (if (looking-at "{") t 0))
  3276. (and pos
  3277. (< 1 (count-lines (+ 3 pos) (point))) ; end of `sub'
  3278. ;; Apparently, we do not need `multiline': faces added now
  3279. (put-text-property (+ 3 pos) (cperl-1+ (point))
  3280. 'syntax-type 'sub-decl))
  3281. (and b-fname ; Fontify here: the following condition
  3282. (cperl-postpone-fontification ; is too hard to determine by
  3283. b-fname e-fname 'face ; a REx, so do it here
  3284. (if (looking-at "{")
  3285. font-lock-function-name-face
  3286. font-lock-variable-name-face)))))
  3287. ;; now restore the initial state
  3288. (if st
  3289. (progn
  3290. (modify-syntax-entry ?\( "." st)
  3291. (modify-syntax-entry ?\) "." st)))
  3292. (if reset-st
  3293. (set-syntax-table reset-st))))
  3294. (defsubst cperl-look-at-leading-count (is-x-REx e)
  3295. (if (and
  3296. (< (point) e)
  3297. (re-search-forward (concat "\\=" (if is-x-REx "[ \t\n]*" "") "[{?+*]")
  3298. (1- e) t)) ; return nil on failure, no moving
  3299. (if (eq ?\{ (preceding-char)) nil
  3300. (cperl-postpone-fontification
  3301. (1- (point)) (point)
  3302. 'face font-lock-warning-face))))
  3303. ;; Do some smarter-highlighting
  3304. ;; XXXX Currently ignores alphanum/dash delims,
  3305. (defsubst cperl-highlight-charclass (endbracket dashface bsface onec-space)
  3306. (let ((l '(1 5 7)) ll lle lll
  3307. ;; 2 groups, the first takes the whole match (include \[trnfabe])
  3308. (singleChar (concat "\\(" "[^\\\\]" "\\|" "\\\\[^cdg-mo-qsu-zA-Z0-9_]" "\\|" "\\\\c." "\\|" "\\\\x" "\\([0-9a-fA-F][0-9a-fA-F]?\\|\\={[0-9a-fA-F]+}\\)" "\\|" "\\\\0?[0-7][0-7]?[0-7]?" "\\|" "\\\\N{[^{}]*}" "\\)")))
  3309. (while ; look for unescaped - between non-classes
  3310. (re-search-forward
  3311. ;; On 19.33, certain simplifications lead
  3312. ;; to bugs (as in [^a-z] \\| [trnfabe] )
  3313. (concat ; 1: SingleChar (include \[trnfabe])
  3314. singleChar
  3315. ;;"\\(" "[^\\\\]" "\\|" "\\\\[^cdg-mo-qsu-zA-Z0-9_]" "\\|" "\\\\c." "\\|" "\\\\x" "\\([0-9a-fA-F][0-9a-fA-F]?\\|\\={[0-9a-fA-F]+}\\)" "\\|" "\\\\0?[0-7][0-7]?[0-7]?" "\\|" "\\\\N{[^{}]*}" "\\)"
  3316. "\\(" ; 3: DASH SingleChar (match optionally)
  3317. "\\(-\\)" ; 4: DASH
  3318. singleChar ; 5: SingleChar
  3319. ;;"\\(" "[^\\\\]" "\\|" "\\\\[^cdg-mo-qsu-zA-Z0-9_]" "\\|" "\\\\c." "\\|" "\\\\x" "\\([0-9a-fA-F][0-9a-fA-F]?\\|\\={[0-9a-fA-F]+}\\)" "\\|" "\\\\0?[0-7][0-7]?[0-7]?" "\\|" "\\\\N{[^{}]*}" "\\)"
  3320. "\\)?"
  3321. "\\|"
  3322. "\\(" ; 7: other escapes
  3323. "\\\\[pP]" "\\([^{]\\|{[^{}]*}\\)"
  3324. "\\|" "\\\\[^pP]" "\\)"
  3325. )
  3326. endbracket 'toend)
  3327. (if (match-beginning 4)
  3328. (cperl-postpone-fontification
  3329. (match-beginning 4) (match-end 4)
  3330. 'face dashface))
  3331. ;; save match data (for looking-at)
  3332. (setq lll (mapcar (function (lambda (elt) (cons (match-beginning elt)
  3333. (match-end elt)))) l))
  3334. (while lll
  3335. (setq ll (car lll))
  3336. (setq lle (cdr ll)
  3337. ll (car ll))
  3338. ;; (message "Got %s of %s" ll l)
  3339. (if (and ll (eq (char-after ll) ?\\ ))
  3340. (save-excursion
  3341. (goto-char ll)
  3342. (cperl-postpone-fontification ll (1+ ll)
  3343. 'face bsface)
  3344. (if (looking-at "\\\\[a-zA-Z0-9]")
  3345. (cperl-postpone-fontification (1+ ll) lle
  3346. 'face onec-space))))
  3347. (setq lll (cdr lll))))
  3348. (goto-char endbracket) ; just in case something misbehaves???
  3349. t))
  3350. ;;; Debugging this may require (setq max-specpdl-size 2000)...
  3351. (defun cperl-find-pods-heres (&optional min max non-inter end ignore-max end-of-here-doc)
  3352. "Scans the buffer for hard-to-parse Perl constructions.
  3353. If `cperl-pod-here-fontify' is not-nil after evaluation, will fontify
  3354. the sections using `cperl-pod-head-face', `cperl-pod-face',
  3355. `cperl-here-face'."
  3356. (interactive)
  3357. (or min (setq min (point-min)
  3358. cperl-syntax-state nil
  3359. cperl-syntax-done-to min))
  3360. (or max (setq max (point-max)))
  3361. (let* ((cperl-pod-here-fontify (eval cperl-pod-here-fontify)) go tmpend
  3362. face head-face here-face b e bb tag qtag b1 e1 argument i c tail tb
  3363. is-REx is-x-REx REx-subgr-start REx-subgr-end was-subgr i2 hairy-RE
  3364. (case-fold-search nil) (inhibit-read-only t) (buffer-undo-list t)
  3365. (modified (buffer-modified-p)) overshoot is-o-REx name
  3366. (after-change-functions nil)
  3367. (cperl-font-locking t)
  3368. (use-syntax-state (and cperl-syntax-state
  3369. (>= min (car cperl-syntax-state))))
  3370. (state-point (if use-syntax-state
  3371. (car cperl-syntax-state)
  3372. (point-min)))
  3373. (state (if use-syntax-state
  3374. (cdr cperl-syntax-state)))
  3375. ;; (st-l '(nil)) (err-l '(nil)) ; Would overwrite - propagates from a function call to a function call!
  3376. (st-l (list nil)) (err-l (list nil))
  3377. ;; Somehow font-lock may be not loaded yet...
  3378. ;; (e.g., when building TAGS via command-line call)
  3379. (font-lock-string-face (if (boundp 'font-lock-string-face)
  3380. font-lock-string-face
  3381. 'font-lock-string-face))
  3382. (my-cperl-delimiters-face (if (boundp 'font-lock-constant-face)
  3383. font-lock-constant-face
  3384. 'font-lock-constant-face))
  3385. (my-cperl-REx-spec-char-face ; [] ^.$ and wrapper-of ({})
  3386. (if (boundp 'font-lock-function-name-face)
  3387. font-lock-function-name-face
  3388. 'font-lock-function-name-face))
  3389. (font-lock-variable-name-face ; interpolated vars and ({})-code
  3390. (if (boundp 'font-lock-variable-name-face)
  3391. font-lock-variable-name-face
  3392. 'font-lock-variable-name-face))
  3393. (font-lock-function-name-face ; used in `cperl-find-sub-attrs'
  3394. (if (boundp 'font-lock-function-name-face)
  3395. font-lock-function-name-face
  3396. 'font-lock-function-name-face))
  3397. (font-lock-constant-face ; used in `cperl-find-sub-attrs'
  3398. (if (boundp 'font-lock-constant-face)
  3399. font-lock-constant-face
  3400. 'font-lock-constant-face))
  3401. (my-cperl-REx-0length-face ; 0-length, (?:)etc, non-literal \
  3402. (if (boundp 'font-lock-builtin-face)
  3403. font-lock-builtin-face
  3404. 'font-lock-builtin-face))
  3405. (font-lock-comment-face
  3406. (if (boundp 'font-lock-comment-face)
  3407. font-lock-comment-face
  3408. 'font-lock-comment-face))
  3409. (font-lock-warning-face
  3410. (if (boundp 'font-lock-warning-face)
  3411. font-lock-warning-face
  3412. 'font-lock-warning-face))
  3413. (my-cperl-REx-ctl-face ; (|)
  3414. (if (boundp 'font-lock-keyword-face)
  3415. font-lock-keyword-face
  3416. 'font-lock-keyword-face))
  3417. (my-cperl-REx-modifiers-face ; //gims
  3418. (if (boundp 'cperl-nonoverridable-face)
  3419. cperl-nonoverridable-face
  3420. 'cperl-nonoverridable-face))
  3421. (my-cperl-REx-length1-face ; length=1 escaped chars, POSIX classes
  3422. (if (boundp 'font-lock-type-face)
  3423. font-lock-type-face
  3424. 'font-lock-type-face))
  3425. (stop-point (if ignore-max
  3426. (point-max)
  3427. max))
  3428. (search
  3429. (concat
  3430. "\\(\\`\n?\\|^\n\\)=" ; POD
  3431. "\\|"
  3432. ;; One extra () before this:
  3433. "<<" ; HERE-DOC
  3434. "\\(" ; 1 + 1
  3435. ;; First variant "BLAH" or just ``.
  3436. "[ \t]*" ; Yes, whitespace is allowed!
  3437. "\\([\"'`]\\)" ; 2 + 1 = 3
  3438. "\\([^\"'`\n]*\\)" ; 3 + 1
  3439. "\\3"
  3440. "\\|"
  3441. ;; Second variant: Identifier or \ID (same as 'ID') or empty
  3442. "\\\\?\\(\\([a-zA-Z_][a-zA-Z_0-9]*\\)?\\)" ; 4 + 1, 5 + 1
  3443. ;; Do not have <<= or << 30 or <<30 or << $blah.
  3444. ;; "\\([^= \t0-9$@%&]\\|[ \t]+[^ \t\n0-9$@%&]\\)" ; 6 + 1
  3445. "\\(\\)" ; To preserve count of pars :-( 6 + 1
  3446. "\\)"
  3447. "\\|"
  3448. ;; 1+6 extra () before this:
  3449. "^[ \t]*\\(format\\)[ \t]*\\([a-zA-Z0-9_]+\\)?[ \t]*=[ \t]*$" ;FRMAT
  3450. (if cperl-use-syntax-table-text-property
  3451. (concat
  3452. "\\|"
  3453. ;; 1+6+2=9 extra () before this:
  3454. "\\<\\(q[wxqr]?\\|[msy]\\|tr\\)\\>" ; QUOTED CONSTRUCT
  3455. "\\|"
  3456. ;; 1+6+2+1=10 extra () before this:
  3457. "\\([?/<]\\)" ; /blah/ or ?blah? or <file*glob>
  3458. "\\|"
  3459. ;; 1+6+2+1+1=11 extra () before this
  3460. "\\<sub\\>" ; sub with proto/attr
  3461. "\\("
  3462. cperl-white-and-comment-rex
  3463. "\\(::[a-zA-Z_:'0-9]*\\|[a-zA-Z_'][a-zA-Z_:'0-9]*\\)\\)?" ; name
  3464. "\\("
  3465. cperl-maybe-white-and-comment-rex
  3466. "\\(([^()]*)\\|:[^:]\\)\\)" ; prototype or attribute start
  3467. "\\|"
  3468. ;; 1+6+2+1+1+6=17 extra () before this:
  3469. "\\$\\(['{]\\)" ; $' or ${foo}
  3470. "\\|"
  3471. ;; 1+6+2+1+1+6+1=18 extra () before this (old pack'var syntax;
  3472. ;; we do not support intervening comments...):
  3473. "\\(\\<sub[ \t\n\f]+\\|[&*$@%]\\)[a-zA-Z0-9_]*'"
  3474. ;; 1+6+2+1+1+6+1+1=19 extra () before this:
  3475. "\\|"
  3476. "__\\(END\\|DATA\\)__" ; __END__ or __DATA__
  3477. ;; 1+6+2+1+1+6+1+1+1=20 extra () before this:
  3478. "\\|"
  3479. "\\\\\\(['`\"($]\\)") ; BACKWACKED something-hairy
  3480. ""))))
  3481. (unwind-protect
  3482. (progn
  3483. (save-excursion
  3484. (or non-inter
  3485. (message "Scanning for \"hard\" Perl constructions..."))
  3486. ;;(message "find: %s --> %s" min max)
  3487. (and cperl-pod-here-fontify
  3488. ;; We had evals here, do not know why...
  3489. (setq face cperl-pod-face
  3490. head-face cperl-pod-head-face
  3491. here-face cperl-here-face))
  3492. (remove-text-properties min max
  3493. '(syntax-type t in-pod t syntax-table t
  3494. attrib-group t
  3495. REx-interpolated t
  3496. cperl-postpone t
  3497. syntax-subtype t
  3498. rear-nonsticky t
  3499. front-sticky t
  3500. here-doc-group t
  3501. first-format-line t
  3502. REx-part2 t
  3503. indentable t))
  3504. ;; Need to remove face as well...
  3505. (goto-char min)
  3506. ;; 'emx not supported by Emacs since at least 21.1.
  3507. (and (featurep 'xemacs) (eq system-type 'emx)
  3508. (eq (point) 1)
  3509. (let ((case-fold-search t))
  3510. (looking-at "extproc[ \t]")) ; Analogue of #!
  3511. (cperl-commentify min
  3512. (point-at-eol)
  3513. nil))
  3514. (while (and
  3515. (< (point) max)
  3516. (re-search-forward search max t))
  3517. (setq tmpend nil) ; Valid for most cases
  3518. (setq b (match-beginning 0)
  3519. state (save-excursion (parse-partial-sexp
  3520. state-point b nil nil state))
  3521. state-point b)
  3522. (cond
  3523. ;; 1+6+2+1+1+6=17 extra () before this:
  3524. ;; "\\$\\(['{]\\)"
  3525. ((match-beginning 18) ; $' or ${foo}
  3526. (if (eq (preceding-char) ?\') ; $'
  3527. (progn
  3528. (setq b (1- (point))
  3529. state (parse-partial-sexp
  3530. state-point (1- b) nil nil state)
  3531. state-point (1- b))
  3532. (if (nth 3 state) ; in string
  3533. (cperl-modify-syntax-type (1- b) cperl-st-punct))
  3534. (goto-char (1+ b)))
  3535. ;; else: ${
  3536. (setq bb (match-beginning 0))
  3537. (cperl-modify-syntax-type bb cperl-st-punct)))
  3538. ;; No processing in strings/comments beyond this point:
  3539. ((or (nth 3 state) (nth 4 state))
  3540. t) ; Do nothing in comment/string
  3541. ((match-beginning 1) ; POD section
  3542. ;; "\\(\\`\n?\\|^\n\\)="
  3543. (setq b (match-beginning 0)
  3544. state (parse-partial-sexp
  3545. state-point b nil nil state)
  3546. state-point b)
  3547. (if (or (nth 3 state) (nth 4 state)
  3548. (looking-at "cut\\>"))
  3549. (if (or (nth 3 state) (nth 4 state) ignore-max)
  3550. nil ; Doing a chunk only
  3551. (message "=cut is not preceded by a POD section")
  3552. (or (car err-l) (setcar err-l (point))))
  3553. (beginning-of-line)
  3554. (setq b (point)
  3555. bb b
  3556. tb (match-beginning 0)
  3557. b1 nil) ; error condition
  3558. ;; We do not search to max, since we may be called from
  3559. ;; some hook of fontification, and max is random
  3560. (or (re-search-forward "^\n=cut\\>" stop-point 'toend)
  3561. (progn
  3562. (goto-char b)
  3563. (if (re-search-forward "\n=cut\\>" stop-point 'toend)
  3564. (progn
  3565. (message "=cut is not preceded by an empty line")
  3566. (setq b1 t)
  3567. (or (car err-l) (setcar err-l b))))))
  3568. (beginning-of-line 2) ; An empty line after =cut is not POD!
  3569. (setq e (point))
  3570. (and (> e max)
  3571. (progn
  3572. (remove-text-properties
  3573. max e '(syntax-type t in-pod t syntax-table t
  3574. attrib-group t
  3575. REx-interpolated t
  3576. cperl-postpone t
  3577. syntax-subtype t
  3578. here-doc-group t
  3579. rear-nonsticky t
  3580. front-sticky t
  3581. first-format-line t
  3582. REx-part2 t
  3583. indentable t))
  3584. (setq tmpend tb)))
  3585. (put-text-property b e 'in-pod t)
  3586. (put-text-property b e 'syntax-type 'in-pod)
  3587. (goto-char b)
  3588. (while (re-search-forward "\n\n[ \t]" e t)
  3589. ;; We start 'pod 1 char earlier to include the preceding line
  3590. (beginning-of-line)
  3591. (put-text-property (cperl-1- b) (point) 'syntax-type 'pod)
  3592. (cperl-put-do-not-fontify b (point) t)
  3593. ;; mark the non-literal parts as PODs
  3594. (if cperl-pod-here-fontify
  3595. (cperl-postpone-fontification b (point) 'face face t))
  3596. (re-search-forward "\n\n[^ \t\f\n]" e 'toend)
  3597. (beginning-of-line)
  3598. (setq b (point)))
  3599. (put-text-property (cperl-1- (point)) e 'syntax-type 'pod)
  3600. (cperl-put-do-not-fontify (point) e t)
  3601. (if cperl-pod-here-fontify
  3602. (progn
  3603. ;; mark the non-literal parts as PODs
  3604. (cperl-postpone-fontification (point) e 'face face t)
  3605. (goto-char bb)
  3606. (if (looking-at
  3607. "=[a-zA-Z0-9_]+\\>[ \t]*\\(\\(\n?[^\n]\\)+\\)$")
  3608. ;; mark the headers
  3609. (cperl-postpone-fontification
  3610. (match-beginning 1) (match-end 1)
  3611. 'face head-face))
  3612. (while (re-search-forward
  3613. ;; One paragraph
  3614. "^\n=[a-zA-Z0-9_]+\\>[ \t]*\\(\\(\n?[^\n]\\)+\\)$"
  3615. e 'toend)
  3616. ;; mark the headers
  3617. (cperl-postpone-fontification
  3618. (match-beginning 1) (match-end 1)
  3619. 'face head-face))))
  3620. (cperl-commentify bb e nil)
  3621. (goto-char e)
  3622. (or (eq e (point-max))
  3623. (forward-char -1)))) ; Prepare for immediate POD start.
  3624. ;; Here document
  3625. ;; We can do many here-per-line;
  3626. ;; but multiline quote on the same line as <<HERE confuses us...
  3627. ;; ;; One extra () before this:
  3628. ;;"<<"
  3629. ;; "\\(" ; 1 + 1
  3630. ;; ;; First variant "BLAH" or just ``.
  3631. ;; "[ \t]*" ; Yes, whitespace is allowed!
  3632. ;; "\\([\"'`]\\)" ; 2 + 1
  3633. ;; "\\([^\"'`\n]*\\)" ; 3 + 1
  3634. ;; "\\3"
  3635. ;; "\\|"
  3636. ;; ;; Second variant: Identifier or \ID or empty
  3637. ;; "\\\\?\\(\\([a-zA-Z_][a-zA-Z_0-9]*\\)?\\)" ; 4 + 1, 5 + 1
  3638. ;; ;; Do not have <<= or << 30 or <<30 or << $blah.
  3639. ;; ;; "\\([^= \t0-9$@%&]\\|[ \t]+[^ \t\n0-9$@%&]\\)" ; 6 + 1
  3640. ;; "\\(\\)" ; To preserve count of pars :-( 6 + 1
  3641. ;; "\\)"
  3642. ((match-beginning 2) ; 1 + 1
  3643. (setq b (point)
  3644. tb (match-beginning 0)
  3645. c (and ; not HERE-DOC
  3646. (match-beginning 5)
  3647. (save-match-data
  3648. (or (looking-at "[ \t]*(") ; << function_call()
  3649. (save-excursion ; 1 << func_name, or $foo << 10
  3650. (condition-case nil
  3651. (progn
  3652. (goto-char tb)
  3653. ;;; XXX What to do: foo <<bar ???
  3654. ;;; XXX Need to support print {a} <<B ???
  3655. (forward-sexp -1)
  3656. (save-match-data
  3657. ; $foo << b; $f .= <<B;
  3658. ; ($f+1) << b; a($f) . <<B;
  3659. ; foo 1, <<B; $x{a} <<b;
  3660. (cond
  3661. ((looking-at "[0-9$({]")
  3662. (forward-sexp 1)
  3663. (and
  3664. (looking-at "[ \t]*<<")
  3665. (condition-case nil
  3666. ;; print $foo <<EOF
  3667. (progn
  3668. (forward-sexp -2)
  3669. (not
  3670. (looking-at "\\(printf?\\|system\\|exec\\|sort\\)\\>")))
  3671. (error t)))))))
  3672. (error nil))) ; func(<<EOF)
  3673. (and (not (match-beginning 6)) ; Empty
  3674. (looking-at
  3675. "[ \t]*[=0-9$@%&(]"))))))
  3676. (if c ; Not here-doc
  3677. nil ; Skip it.
  3678. (setq c (match-end 2)) ; 1 + 1
  3679. (if (match-beginning 5) ;4 + 1
  3680. (setq b1 (match-beginning 5) ; 4 + 1
  3681. e1 (match-end 5)) ; 4 + 1
  3682. (setq b1 (match-beginning 4) ; 3 + 1
  3683. e1 (match-end 4))) ; 3 + 1
  3684. (setq tag (buffer-substring b1 e1)
  3685. qtag (regexp-quote tag))
  3686. (cond (cperl-pod-here-fontify
  3687. ;; Highlight the starting delimiter
  3688. (cperl-postpone-fontification
  3689. b1 e1 'face my-cperl-delimiters-face)
  3690. (cperl-put-do-not-fontify b1 e1 t)))
  3691. (forward-line)
  3692. (setq i (point))
  3693. (if end-of-here-doc
  3694. (goto-char end-of-here-doc))
  3695. (setq b (point))
  3696. ;; We do not search to max, since we may be called from
  3697. ;; some hook of fontification, and max is random
  3698. (or (and (re-search-forward (concat "^" qtag "$")
  3699. stop-point 'toend)
  3700. ;;;(eq (following-char) ?\n) ; XXXX WHY???
  3701. )
  3702. (progn ; Pretend we matched at the end
  3703. (goto-char (point-max))
  3704. (re-search-forward "\\'")
  3705. (message "End of here-document `%s' not found." tag)
  3706. (or (car err-l) (setcar err-l b))))
  3707. (if cperl-pod-here-fontify
  3708. (progn
  3709. ;; Highlight the ending delimiter
  3710. (cperl-postpone-fontification
  3711. (match-beginning 0) (match-end 0)
  3712. 'face my-cperl-delimiters-face)
  3713. (cperl-put-do-not-fontify b (match-end 0) t)
  3714. ;; Highlight the HERE-DOC
  3715. (cperl-postpone-fontification b (match-beginning 0)
  3716. 'face here-face)))
  3717. (setq e1 (cperl-1+ (match-end 0)))
  3718. (put-text-property b (match-beginning 0)
  3719. 'syntax-type 'here-doc)
  3720. (put-text-property (match-beginning 0) e1
  3721. 'syntax-type 'here-doc-delim)
  3722. (put-text-property b e1 'here-doc-group t)
  3723. ;; This makes insertion at the start of HERE-DOC update
  3724. ;; the whole construct:
  3725. (put-text-property b (cperl-1+ b) 'front-sticky '(syntax-type))
  3726. (cperl-commentify b e1 nil)
  3727. (cperl-put-do-not-fontify b (match-end 0) t)
  3728. ;; Cache the syntax info...
  3729. (setq cperl-syntax-state (cons state-point state))
  3730. ;; ... and process the rest of the line...
  3731. (setq overshoot
  3732. (elt ; non-inter ignore-max
  3733. (cperl-find-pods-heres c i t end t e1) 1))
  3734. (if (and overshoot (> overshoot (point)))
  3735. (goto-char overshoot)
  3736. (setq overshoot e1))
  3737. (if (> e1 max)
  3738. (setq tmpend tb))))
  3739. ;; format
  3740. ((match-beginning 8)
  3741. ;; 1+6=7 extra () before this:
  3742. ;;"^[ \t]*\\(format\\)[ \t]*\\([a-zA-Z0-9_]+\\)?[ \t]*=[ \t]*$"
  3743. (setq b (point)
  3744. name (if (match-beginning 8) ; 7 + 1
  3745. (buffer-substring (match-beginning 8) ; 7 + 1
  3746. (match-end 8)) ; 7 + 1
  3747. "")
  3748. tb (match-beginning 0))
  3749. (setq argument nil)
  3750. (put-text-property (point-at-bol) b 'first-format-line 't)
  3751. (if cperl-pod-here-fontify
  3752. (while (and (eq (forward-line) 0)
  3753. (not (looking-at "^[.;]$")))
  3754. (cond
  3755. ((looking-at "^#")) ; Skip comments
  3756. ((and argument ; Skip argument multi-lines
  3757. (looking-at "^[ \t]*{"))
  3758. (forward-sexp 1)
  3759. (setq argument nil))
  3760. (argument ; Skip argument lines
  3761. (setq argument nil))
  3762. (t ; Format line
  3763. (setq b1 (point))
  3764. (setq argument (looking-at "^[^\n]*[@^]"))
  3765. (end-of-line)
  3766. ;; Highlight the format line
  3767. (cperl-postpone-fontification b1 (point)
  3768. 'face font-lock-string-face)
  3769. (cperl-commentify b1 (point) nil)
  3770. (cperl-put-do-not-fontify b1 (point) t))))
  3771. ;; We do not search to max, since we may be called from
  3772. ;; some hook of fontification, and max is random
  3773. (re-search-forward "^[.;]$" stop-point 'toend))
  3774. (beginning-of-line)
  3775. (if (looking-at "^\\.$") ; ";" is not supported yet
  3776. (progn
  3777. ;; Highlight the ending delimiter
  3778. (cperl-postpone-fontification (point) (+ (point) 2)
  3779. 'face font-lock-string-face)
  3780. (cperl-commentify (point) (+ (point) 2) nil)
  3781. (cperl-put-do-not-fontify (point) (+ (point) 2) t))
  3782. (message "End of format `%s' not found." name)
  3783. (or (car err-l) (setcar err-l b)))
  3784. (forward-line)
  3785. (if (> (point) max)
  3786. (setq tmpend tb))
  3787. (put-text-property b (point) 'syntax-type 'format))
  3788. ;; qq-like String or Regexp:
  3789. ((or (match-beginning 10) (match-beginning 11))
  3790. ;; 1+6+2=9 extra () before this:
  3791. ;; "\\<\\(q[wxqr]?\\|[msy]\\|tr\\)\\>"
  3792. ;; "\\|"
  3793. ;; "\\([?/<]\\)" ; /blah/ or ?blah? or <file*glob>
  3794. (setq b1 (if (match-beginning 10) 10 11)
  3795. argument (buffer-substring
  3796. (match-beginning b1) (match-end b1))
  3797. b (point) ; end of qq etc
  3798. i b
  3799. c (char-after (match-beginning b1))
  3800. bb (char-after (1- (match-beginning b1))) ; tmp holder
  3801. ;; bb == "Not a stringy"
  3802. bb (if (eq b1 10) ; user variables/whatever
  3803. (and (memq bb (append "$@%*#_:-&>" nil)) ; $#y)
  3804. (cond ((eq bb ?-) (eq c ?s)) ; -s file test
  3805. ((eq bb ?\:) ; $opt::s
  3806. (eq (char-after
  3807. (- (match-beginning b1) 2))
  3808. ?\:))
  3809. ((eq bb ?\>) ; $foo->s
  3810. (eq (char-after
  3811. (- (match-beginning b1) 2))
  3812. ?\-))
  3813. ((eq bb ?\&)
  3814. (not (eq (char-after ; &&m/blah/
  3815. (- (match-beginning b1) 2))
  3816. ?\&)))
  3817. (t t)))
  3818. ;; <file> or <$file>
  3819. (and (eq c ?\<)
  3820. ;; Do not stringify <FH>, <$fh> :
  3821. (save-match-data
  3822. (looking-at
  3823. "\\$?\\([_a-zA-Z:][_a-zA-Z0-9:]*\\)?>"))))
  3824. tb (match-beginning 0))
  3825. (goto-char (match-beginning b1))
  3826. (cperl-backward-to-noncomment (point-min))
  3827. (or bb
  3828. (if (eq b1 11) ; bare /blah/ or ?blah? or <foo>
  3829. (setq argument ""
  3830. b1 nil
  3831. bb ; Not a regexp?
  3832. (not
  3833. ;; What is below: regexp-p?
  3834. (and
  3835. (or (memq (preceding-char)
  3836. (append (if (memq c '(?\? ?\<))
  3837. ;; $a++ ? 1 : 2
  3838. "~{(=|&*!,;:["
  3839. "~{(=|&+-*!,;:[") nil))
  3840. (and (eq (preceding-char) ?\})
  3841. (cperl-after-block-p (point-min)))
  3842. (and (eq (char-syntax (preceding-char)) ?w)
  3843. (progn
  3844. (forward-sexp -1)
  3845. ;; After these keywords `/' starts a RE. One should add all the
  3846. ;; functions/builtins which expect an argument, but ...
  3847. (if (eq (preceding-char) ?-)
  3848. ;; -d ?foo? is a RE
  3849. (looking-at "[a-zA-Z]\\>")
  3850. (and
  3851. (not (memq (preceding-char)
  3852. '(?$ ?@ ?& ?%)))
  3853. (looking-at
  3854. "\\(while\\|if\\|unless\\|until\\|and\\|or\\|not\\|xor\\|split\\|grep\\|map\\|print\\)\\>")))))
  3855. (and (eq (preceding-char) ?.)
  3856. (eq (char-after (- (point) 2)) ?.))
  3857. (bobp))
  3858. ;; m|blah| ? foo : bar;
  3859. (not
  3860. (and (eq c ?\?)
  3861. cperl-use-syntax-table-text-property
  3862. (not (bobp))
  3863. (progn
  3864. (forward-char -1)
  3865. (looking-at "\\s|"))))))
  3866. b (1- b))
  3867. ;; s y tr m
  3868. ;; Check for $a -> y
  3869. (setq b1 (preceding-char)
  3870. go (point))
  3871. (if (and (eq b1 ?>)
  3872. (eq (char-after (- go 2)) ?-))
  3873. ;; Not a regexp
  3874. (setq bb t))))
  3875. (or bb
  3876. (progn
  3877. (goto-char b)
  3878. (if (looking-at "[ \t\n\f]+\\(#[^\n]*\n[ \t\n\f]*\\)+")
  3879. (goto-char (match-end 0))
  3880. (skip-chars-forward " \t\n\f"))
  3881. (cond ((and (eq (following-char) ?\})
  3882. (eq b1 ?\{))
  3883. ;; Check for $a[23]->{ s }, @{s} and *{s::foo}
  3884. (goto-char (1- go))
  3885. (skip-chars-backward " \t\n\f")
  3886. (if (memq (preceding-char) (append "$@%&*" nil))
  3887. (setq bb t) ; @{y}
  3888. (condition-case nil
  3889. (forward-sexp -1)
  3890. (error nil)))
  3891. (if (or bb
  3892. (looking-at ; $foo -> {s}
  3893. "[$@]\\$*\\([a-zA-Z0-9_:]+\\|[^{]\\)\\([ \t\n]*->\\)?[ \t\n]*{")
  3894. (and ; $foo[12] -> {s}
  3895. (memq (following-char) '(?\{ ?\[))
  3896. (progn
  3897. (forward-sexp 1)
  3898. (looking-at "\\([ \t\n]*->\\)?[ \t\n]*{"))))
  3899. (setq bb t)
  3900. (goto-char b)))
  3901. ((and (eq (following-char) ?=)
  3902. (eq (char-after (1+ (point))) ?\>))
  3903. ;; Check for { foo => 1, s => 2 }
  3904. ;; Apparently s=> is never a substitution...
  3905. (setq bb t))
  3906. ((and (eq (following-char) ?:)
  3907. (eq b1 ?\{) ; Check for $ { s::bar }
  3908. (looking-at "::[a-zA-Z0-9_:]*[ \t\n\f]*}")
  3909. (progn
  3910. (goto-char (1- go))
  3911. (skip-chars-backward " \t\n\f")
  3912. (memq (preceding-char)
  3913. (append "$@%&*" nil))))
  3914. (setq bb t))
  3915. ((eobp)
  3916. (setq bb t)))))
  3917. (if bb
  3918. (goto-char i)
  3919. ;; Skip whitespace and comments...
  3920. (if (looking-at "[ \t\n\f]+\\(#[^\n]*\n[ \t\n\f]*\\)+")
  3921. (goto-char (match-end 0))
  3922. (skip-chars-forward " \t\n\f"))
  3923. (if (> (point) b)
  3924. (put-text-property b (point) 'syntax-type 'prestring))
  3925. ;; qtag means two-arg matcher, may be reset to
  3926. ;; 2 or 3 later if some special quoting is needed.
  3927. ;; e1 means matching-char matcher.
  3928. (setq b (point) ; before the first delimiter
  3929. ;; has 2 args
  3930. i2 (string-match "^\\([sy]\\|tr\\)$" argument)
  3931. ;; We do not search to max, since we may be called from
  3932. ;; some hook of fontification, and max is random
  3933. i (cperl-forward-re stop-point end
  3934. i2
  3935. st-l err-l argument)
  3936. ;; If `go', then it is considered as 1-arg, `b1' is nil
  3937. ;; as in s/foo//x; the point is before final "slash"
  3938. b1 (nth 1 i) ; start of the second part
  3939. tag (nth 2 i) ; ender-char, true if second part
  3940. ; is with matching chars []
  3941. go (nth 4 i) ; There is a 1-char part after the end
  3942. i (car i) ; intermediate point
  3943. e1 (point) ; end
  3944. ;; Before end of the second part if non-matching: ///
  3945. tail (if (and i (not tag))
  3946. (1- e1))
  3947. e (if i i e1) ; end of the first part
  3948. qtag nil ; need to preserve backslashitis
  3949. is-x-REx nil is-o-REx nil); REx has //x //o modifiers
  3950. ;; If s{} (), then b/b1 are at "{", "(", e1/i after ")", "}"
  3951. ;; Commenting \\ is dangerous, what about ( ?
  3952. (and i tail
  3953. (eq (char-after i) ?\\)
  3954. (setq qtag t))
  3955. (and (if go (looking-at ".\\sw*x")
  3956. (looking-at "\\sw*x")) ; qr//x
  3957. (setq is-x-REx t))
  3958. (and (if go (looking-at ".\\sw*o")
  3959. (looking-at "\\sw*o")) ; //o
  3960. (setq is-o-REx t))
  3961. (if (null i)
  3962. ;; Considered as 1arg form
  3963. (progn
  3964. (cperl-commentify b (point) t)
  3965. (put-text-property b (point) 'syntax-type 'string)
  3966. (if (or is-x-REx
  3967. ;; ignore other text properties:
  3968. (string-match "^qw$" argument))
  3969. (put-text-property b (point) 'indentable t))
  3970. (and go
  3971. (setq e1 (cperl-1+ e1))
  3972. (or (eobp)
  3973. (forward-char 1))))
  3974. (cperl-commentify b i t)
  3975. (if (looking-at "\\sw*e") ; s///e
  3976. (progn
  3977. ;; Cache the syntax info...
  3978. (setq cperl-syntax-state (cons state-point state))
  3979. (and
  3980. ;; silent:
  3981. (car (cperl-find-pods-heres b1 (1- (point)) t end))
  3982. ;; Error
  3983. (goto-char (1+ max)))
  3984. (if (and tag (eq (preceding-char) ?\>))
  3985. (progn
  3986. (cperl-modify-syntax-type (1- (point)) cperl-st-ket)
  3987. (cperl-modify-syntax-type i cperl-st-bra)))
  3988. (put-text-property b i 'syntax-type 'string)
  3989. (put-text-property i (point) 'syntax-type 'multiline)
  3990. (if is-x-REx
  3991. (put-text-property b i 'indentable t)))
  3992. (cperl-commentify b1 (point) t)
  3993. (put-text-property b (point) 'syntax-type 'string)
  3994. (if is-x-REx
  3995. (put-text-property b i 'indentable t))
  3996. (if qtag
  3997. (cperl-modify-syntax-type (1+ i) cperl-st-punct))
  3998. (setq tail nil)))
  3999. ;; Now: tail: if the second part is non-matching without ///e
  4000. (if (eq (char-syntax (following-char)) ?w)
  4001. (progn
  4002. (forward-word 1) ; skip modifiers s///s
  4003. (if tail (cperl-commentify tail (point) t))
  4004. (cperl-postpone-fontification
  4005. e1 (point) 'face my-cperl-REx-modifiers-face)))
  4006. ;; Check whether it is m// which means "previous match"
  4007. ;; and highlight differently
  4008. (setq is-REx
  4009. (and (string-match "^\\([sm]?\\|qr\\)$" argument)
  4010. (or (not (= (length argument) 0))
  4011. (not (eq c ?\<)))))
  4012. (if (and is-REx
  4013. (eq e (+ 2 b))
  4014. ;; split // *is* using zero-pattern
  4015. (save-excursion
  4016. (condition-case nil
  4017. (progn
  4018. (goto-char tb)
  4019. (forward-sexp -1)
  4020. (not (looking-at "split\\>")))
  4021. (error t))))
  4022. (cperl-postpone-fontification
  4023. b e 'face font-lock-warning-face)
  4024. (if (or i2 ; Has 2 args
  4025. (and cperl-fontify-m-as-s
  4026. (or
  4027. (string-match "^\\(m\\|qr\\)$" argument)
  4028. (and (eq 0 (length argument))
  4029. (not (eq ?\< (char-after b)))))))
  4030. (progn
  4031. (cperl-postpone-fontification
  4032. b (cperl-1+ b) 'face my-cperl-delimiters-face)
  4033. (cperl-postpone-fontification
  4034. (1- e) e 'face my-cperl-delimiters-face)))
  4035. (if (and is-REx cperl-regexp-scan)
  4036. ;; Process RExen: embedded comments, charclasses and ]
  4037. ;;;/\3333\xFg\x{FFF}a\ppp\PPP\qqq\C\99f(?{ foo })(??{ foo })/;
  4038. ;;;/a\.b[^a[:ff:]b]x$ab->$[|$,$ab->[cd]->[ef]|$ab[xy].|^${a,b}{c,d}/;
  4039. ;;;/(?<=foo)(?<!bar)(x)(?:$ab|\$\/)$|\\\b\x888\776\[\:$/xxx;
  4040. ;;;m?(\?\?{b,a})? + m/(??{aa})(?(?=xx)aa|bb)(?#aac)/;
  4041. ;;;m$(^ab[c]\$)$ + m+(^ab[c]\$\+)+ + m](^ab[c\]$|.+)] + m)(^ab[c]$|.+\));
  4042. ;;;m^a[\^b]c^ + m.a[^b]\.c.;
  4043. (save-excursion
  4044. (goto-char (1+ b))
  4045. ;; First
  4046. (cperl-look-at-leading-count is-x-REx e)
  4047. (setq hairy-RE
  4048. (concat
  4049. (if is-x-REx
  4050. (if (eq (char-after b) ?\#)
  4051. "\\((\\?\\\\#\\)\\|\\(\\\\#\\)"
  4052. "\\((\\?#\\)\\|\\(#\\)")
  4053. ;; keep the same count: add a fake group
  4054. (if (eq (char-after b) ?\#)
  4055. "\\((\\?\\\\#\\)\\(\\)"
  4056. "\\((\\?#\\)\\(\\)"))
  4057. "\\|"
  4058. "\\(\\[\\)" ; 3=[
  4059. "\\|"
  4060. "\\(]\\)" ; 4=]
  4061. "\\|"
  4062. ;; XXXX Will not be able to use it in s)))
  4063. (if (eq (char-after b) ?\) )
  4064. "\\())))\\)" ; Will never match
  4065. (if (eq (char-after b) ?? )
  4066. ;;"\\((\\\\\\?\\(\\\\\\?\\)?{\\)"
  4067. "\\((\\\\\\?\\\\\\?{\\|()\\\\\\?{\\)"
  4068. "\\((\\?\\??{\\)")) ; 5= (??{ (?{
  4069. "\\|" ; 6= 0-length, 7: name, 8,9:code, 10:group
  4070. "\\(" ;; XXXX 1-char variables, exc. |()\s
  4071. "[$@]"
  4072. "\\("
  4073. "[_a-zA-Z:][_a-zA-Z0-9:]*"
  4074. "\\|"
  4075. "{[^{}]*}" ; only one-level allowed
  4076. "\\|"
  4077. "[^{(|) \t\r\n\f]"
  4078. "\\)"
  4079. "\\(" ;;8,9:code part of array/hash elt
  4080. "\\(" "->" "\\)?"
  4081. "\\[[^][]*\\]"
  4082. "\\|"
  4083. "{[^{}]*}"
  4084. "\\)*"
  4085. ;; XXXX: what if u is delim?
  4086. "\\|"
  4087. "[)^|$.*?+]"
  4088. "\\|"
  4089. "{[0-9]+}"
  4090. "\\|"
  4091. "{[0-9]+,[0-9]*}"
  4092. "\\|"
  4093. "\\\\[luLUEQbBAzZG]"
  4094. "\\|"
  4095. "(" ; Group opener
  4096. "\\(" ; 10 group opener follower
  4097. "\\?\\((\\?\\)" ; 11: in (?(?=C)A|B)
  4098. "\\|"
  4099. "\\?[:=!>?{]" ; "?" something
  4100. "\\|"
  4101. "\\?[-imsx]+[:)]" ; (?i) (?-s:.)
  4102. "\\|"
  4103. "\\?([0-9]+)" ; (?(1)foo|bar)
  4104. "\\|"
  4105. "\\?<[=!]"
  4106. ;;;"\\|"
  4107. ;;; "\\?"
  4108. "\\)?"
  4109. "\\)"
  4110. "\\|"
  4111. "\\\\\\(.\\)" ; 12=\SYMBOL
  4112. ))
  4113. (while
  4114. (and (< (point) (1- e))
  4115. (re-search-forward hairy-RE (1- e) 'to-end))
  4116. (goto-char (match-beginning 0))
  4117. (setq REx-subgr-start (point)
  4118. was-subgr (following-char))
  4119. (cond
  4120. ((match-beginning 6) ; 0-length builtins, groups
  4121. (goto-char (match-end 0))
  4122. (if (match-beginning 11)
  4123. (goto-char (match-beginning 11)))
  4124. (if (>= (point) e)
  4125. (goto-char (1- e)))
  4126. (cperl-postpone-fontification
  4127. (match-beginning 0) (point)
  4128. 'face
  4129. (cond
  4130. ((eq was-subgr ?\) )
  4131. (condition-case nil
  4132. (save-excursion
  4133. (forward-sexp -1)
  4134. (if (> (point) b)
  4135. (if (if (eq (char-after b) ?? )
  4136. (looking-at "(\\\\\\?")
  4137. (eq (char-after (1+ (point))) ?\?))
  4138. my-cperl-REx-0length-face
  4139. my-cperl-REx-ctl-face)
  4140. font-lock-warning-face))
  4141. (error font-lock-warning-face)))
  4142. ((eq was-subgr ?\| )
  4143. my-cperl-REx-ctl-face)
  4144. ((eq was-subgr ?\$ )
  4145. (if (> (point) (1+ REx-subgr-start))
  4146. (progn
  4147. (put-text-property
  4148. (match-beginning 0) (point)
  4149. 'REx-interpolated
  4150. (if is-o-REx 0
  4151. (if (and (eq (match-beginning 0)
  4152. (1+ b))
  4153. (eq (point)
  4154. (1- e))) 1 t)))
  4155. font-lock-variable-name-face)
  4156. my-cperl-REx-spec-char-face))
  4157. ((memq was-subgr (append "^." nil) )
  4158. my-cperl-REx-spec-char-face)
  4159. ((eq was-subgr ?\( )
  4160. (if (not (match-beginning 10))
  4161. my-cperl-REx-ctl-face
  4162. my-cperl-REx-0length-face))
  4163. (t my-cperl-REx-0length-face)))
  4164. (if (and (memq was-subgr (append "(|" nil))
  4165. (not (string-match "(\\?[-imsx]+)"
  4166. (match-string 0))))
  4167. (cperl-look-at-leading-count is-x-REx e))
  4168. (setq was-subgr nil)) ; We do stuff here
  4169. ((match-beginning 12) ; \SYMBOL
  4170. (forward-char 2)
  4171. (if (>= (point) e)
  4172. (goto-char (1- e))
  4173. ;; How many chars to not highlight:
  4174. ;; 0-len special-alnums in other branch =>
  4175. ;; Generic: \non-alnum (1), \alnum (1+face)
  4176. ;; Is-delim: \non-alnum (1/spec-2) alnum-1 (=what hai)
  4177. (setq REx-subgr-start (point)
  4178. qtag (preceding-char))
  4179. (cperl-postpone-fontification
  4180. (- (point) 2) (- (point) 1) 'face
  4181. (if (memq qtag
  4182. (append "ghijkmoqvFHIJKMORTVY" nil))
  4183. font-lock-warning-face
  4184. my-cperl-REx-0length-face))
  4185. (if (and (eq (char-after b) qtag)
  4186. (memq qtag (append ".])^$|*?+" nil)))
  4187. (progn
  4188. (if (and cperl-use-syntax-table-text-property
  4189. (eq qtag ?\) ))
  4190. (put-text-property
  4191. REx-subgr-start (1- (point))
  4192. 'syntax-table cperl-st-punct))
  4193. (cperl-postpone-fontification
  4194. (1- (point)) (point) 'face
  4195. ; \] can't appear below
  4196. (if (memq qtag (append ".]^$" nil))
  4197. 'my-cperl-REx-spec-char-face
  4198. (if (memq qtag (append "*?+" nil))
  4199. 'my-cperl-REx-0length-face
  4200. 'my-cperl-REx-ctl-face))))) ; )|
  4201. ;; Test for arguments:
  4202. (cond
  4203. ;; This is not pretty: the 5.8.7 logic:
  4204. ;; \0numx -> octal (up to total 3 dig)
  4205. ;; \DIGIT -> backref unless \0
  4206. ;; \DIGITs -> backref if valid
  4207. ;; otherwise up to 3 -> octal
  4208. ;; Do not try to distinguish, we guess
  4209. ((or (and (memq qtag (append "01234567" nil))
  4210. (re-search-forward
  4211. "\\=[01234567]?[01234567]?"
  4212. (1- e) 'to-end))
  4213. (and (memq qtag (append "89" nil))
  4214. (re-search-forward
  4215. "\\=[0123456789]*" (1- e) 'to-end))
  4216. (and (eq qtag ?x)
  4217. (re-search-forward
  4218. "\\=[0-9a-fA-F][0-9a-fA-F]?\\|\\={[0-9a-fA-F]+}"
  4219. (1- e) 'to-end))
  4220. (and (memq qtag (append "pPN" nil))
  4221. (re-search-forward "\\={[^{}]+}\\|."
  4222. (1- e) 'to-end))
  4223. (eq (char-syntax qtag) ?w))
  4224. (cperl-postpone-fontification
  4225. (1- REx-subgr-start) (point)
  4226. 'face my-cperl-REx-length1-face))))
  4227. (setq was-subgr nil)) ; We do stuff here
  4228. ((match-beginning 3) ; [charclass]
  4229. ;; Highlight leader, trailer, POSIX classes
  4230. (forward-char 1)
  4231. (if (eq (char-after b) ?^ )
  4232. (and (eq (following-char) ?\\ )
  4233. (eq (char-after (cperl-1+ (point)))
  4234. ?^ )
  4235. (forward-char 2))
  4236. (and (eq (following-char) ?^ )
  4237. (forward-char 1)))
  4238. (setq argument b ; continue? & end of last POSIX
  4239. tag nil ; list of POSIX classes
  4240. qtag (point)) ; after leading ^ if present
  4241. (if (eq (char-after b) ?\] )
  4242. (and (eq (following-char) ?\\ )
  4243. (eq (char-after (cperl-1+ (point)))
  4244. ?\] )
  4245. (setq qtag (1+ qtag))
  4246. (forward-char 2))
  4247. (and (eq (following-char) ?\] )
  4248. (forward-char 1)))
  4249. (setq REx-subgr-end qtag) ;End smart-highlighted
  4250. ;; Apparently, I can't put \] into a charclass
  4251. ;; in m]]: m][\\\]\]] produces [\\]]
  4252. ;;; POSIX? [:word:] [:^word:] only inside []
  4253. ;;; "\\=\\(\\\\.\\|[^][\\\\]\\|\\[:\\^?\sw+:]\\|\\[[^:]\\)*]")
  4254. (while ; look for unescaped ]
  4255. (and argument
  4256. (re-search-forward
  4257. (if (eq (char-after b) ?\] )
  4258. "\\=\\(\\\\[^]]\\|[^]\\\\]\\)*\\\\]"
  4259. "\\=\\(\\\\.\\|[^]\\\\]\\)*]")
  4260. (1- e) 'toend))
  4261. ;; Is this ] an end of POSIX class?
  4262. (if (save-excursion
  4263. (and
  4264. (search-backward "[" argument t)
  4265. (< REx-subgr-start (point))
  4266. (setq argument (point)) ; POSIX-start
  4267. (or ; Should work with delim = \
  4268. (not (eq (preceding-char) ?\\ ))
  4269. ;; XXXX Double \\ is needed with 19.33
  4270. (= (% (skip-chars-backward "\\\\") 2) 0))
  4271. (looking-at
  4272. (cond
  4273. ((eq (char-after b) ?\] )
  4274. "\\\\*\\[:\\^?\\sw+:\\\\\\]")
  4275. ((eq (char-after b) ?\: )
  4276. "\\\\*\\[\\\\:\\^?\\sw+\\\\:]")
  4277. ((eq (char-after b) ?^ )
  4278. "\\\\*\\[:\\(\\\\\\^\\)?\\sw+:\]")
  4279. ((eq (char-syntax (char-after b))
  4280. ?w)
  4281. (concat
  4282. "\\\\*\\[:\\(\\\\\\^\\)?\\(\\\\"
  4283. (char-to-string (char-after b))
  4284. "\\|\\sw\\)+:\]"))
  4285. (t "\\\\*\\[:\\^?\\sw*:]")))
  4286. (goto-char REx-subgr-end)
  4287. (cperl-highlight-charclass
  4288. argument my-cperl-REx-spec-char-face
  4289. my-cperl-REx-0length-face my-cperl-REx-length1-face)))
  4290. (setq tag (cons (cons argument (point))
  4291. tag)
  4292. argument (point)
  4293. REx-subgr-end argument) ; continue
  4294. (setq argument nil)))
  4295. (and argument
  4296. (message "Couldn't find end of charclass in a REx, pos=%s"
  4297. REx-subgr-start))
  4298. (setq argument (1- (point)))
  4299. (goto-char REx-subgr-end)
  4300. (cperl-highlight-charclass
  4301. argument my-cperl-REx-spec-char-face
  4302. my-cperl-REx-0length-face my-cperl-REx-length1-face)
  4303. (forward-char 1)
  4304. ;; Highlight starter, trailer, POSIX
  4305. (if (and cperl-use-syntax-table-text-property
  4306. (> (- (point) 2) REx-subgr-start))
  4307. (put-text-property
  4308. (1+ REx-subgr-start) (1- (point))
  4309. 'syntax-table cperl-st-punct))
  4310. (cperl-postpone-fontification
  4311. REx-subgr-start qtag
  4312. 'face my-cperl-REx-spec-char-face)
  4313. (cperl-postpone-fontification
  4314. (1- (point)) (point) 'face
  4315. my-cperl-REx-spec-char-face)
  4316. (if (eq (char-after b) ?\] )
  4317. (cperl-postpone-fontification
  4318. (- (point) 2) (1- (point))
  4319. 'face my-cperl-REx-0length-face))
  4320. (while tag
  4321. (cperl-postpone-fontification
  4322. (car (car tag)) (cdr (car tag))
  4323. 'face font-lock-variable-name-face) ;my-cperl-REx-length1-face
  4324. (setq tag (cdr tag)))
  4325. (setq was-subgr nil)) ; did facing already
  4326. ;; Now rare stuff:
  4327. ((and (match-beginning 2) ; #-comment
  4328. (/= (match-beginning 2) (match-end 2)))
  4329. (beginning-of-line 2)
  4330. (if (> (point) e)
  4331. (goto-char (1- e))))
  4332. ((match-beginning 4) ; character "]"
  4333. (setq was-subgr nil) ; We do stuff here
  4334. (goto-char (match-end 0))
  4335. (if cperl-use-syntax-table-text-property
  4336. (put-text-property
  4337. (1- (point)) (point)
  4338. 'syntax-table cperl-st-punct))
  4339. (cperl-postpone-fontification
  4340. (1- (point)) (point)
  4341. 'face font-lock-warning-face))
  4342. ((match-beginning 5) ; before (?{}) (??{})
  4343. (setq tag (match-end 0))
  4344. (if (or (setq qtag
  4345. (cperl-forward-group-in-re st-l))
  4346. (and (>= (point) e)
  4347. (setq qtag "no matching `)' found"))
  4348. (and (not (eq (char-after (- (point) 2))
  4349. ?\} ))
  4350. (setq qtag "Can't find })")))
  4351. (progn
  4352. (goto-char (1- e))
  4353. (message "%s" qtag))
  4354. (cperl-postpone-fontification
  4355. (1- tag) (1- (point))
  4356. 'face font-lock-variable-name-face)
  4357. (cperl-postpone-fontification
  4358. REx-subgr-start (1- tag)
  4359. 'face my-cperl-REx-spec-char-face)
  4360. (cperl-postpone-fontification
  4361. (1- (point)) (point)
  4362. 'face my-cperl-REx-spec-char-face)
  4363. (if cperl-use-syntax-table-text-property
  4364. (progn
  4365. (put-text-property
  4366. (- (point) 2) (1- (point))
  4367. 'syntax-table cperl-st-cfence)
  4368. (put-text-property
  4369. (+ REx-subgr-start 2)
  4370. (+ REx-subgr-start 3)
  4371. 'syntax-table cperl-st-cfence))))
  4372. (setq was-subgr nil))
  4373. (t ; (?#)-comment
  4374. ;; Inside "(" and "\" arn't special in any way
  4375. ;; Works also if the outside delimiters are ().
  4376. (or;;(if (eq (char-after b) ?\) )
  4377. ;;(re-search-forward
  4378. ;; "[^\\\\]\\(\\\\\\\\\\)*\\\\)"
  4379. ;; (1- e) 'toend)
  4380. (search-forward ")" (1- e) 'toend)
  4381. ;;)
  4382. (message
  4383. "Couldn't find end of (?#...)-comment in a REx, pos=%s"
  4384. REx-subgr-start))))
  4385. (if (>= (point) e)
  4386. (goto-char (1- e)))
  4387. (cond
  4388. (was-subgr
  4389. (setq REx-subgr-end (point))
  4390. (cperl-commentify
  4391. REx-subgr-start REx-subgr-end nil)
  4392. (cperl-postpone-fontification
  4393. REx-subgr-start REx-subgr-end
  4394. 'face font-lock-comment-face))))))
  4395. (if (and is-REx is-x-REx)
  4396. (put-text-property (1+ b) (1- e)
  4397. 'syntax-subtype 'x-REx)))
  4398. (if (and i2 e1 (or (not b1) (> e1 b1)))
  4399. (progn ; No errors finding the second part...
  4400. (cperl-postpone-fontification
  4401. (1- e1) e1 'face my-cperl-delimiters-face)
  4402. (if (and (not (eobp))
  4403. (assoc (char-after b) cperl-starters))
  4404. (progn
  4405. (cperl-postpone-fontification
  4406. b1 (1+ b1) 'face my-cperl-delimiters-face)
  4407. (put-text-property b1 (1+ b1)
  4408. 'REx-part2 t)))))
  4409. (if (> (point) max)
  4410. (setq tmpend tb))))
  4411. ((match-beginning 17) ; sub with prototype or attribute
  4412. ;; 1+6+2+1+1=11 extra () before this (sub with proto/attr):
  4413. ;;"\\<sub\\>\\(" ;12
  4414. ;; cperl-white-and-comment-rex ;13
  4415. ;; "\\([a-zA-Z_:'0-9]+\\)\\)?" ; name ;14
  4416. ;;"\\(" cperl-maybe-white-and-comment-rex ;15,16
  4417. ;; "\\(([^()]*)\\|:[^:]\\)\\)" ; 17:proto or attribute start
  4418. (setq b1 (match-beginning 14) e1 (match-end 14))
  4419. (if (memq (char-after (1- b))
  4420. '(?\$ ?\@ ?\% ?\& ?\*))
  4421. nil
  4422. (goto-char b)
  4423. (if (eq (char-after (match-beginning 17)) ?\( )
  4424. (progn
  4425. (cperl-commentify ; Prototypes; mark as string
  4426. (match-beginning 17) (match-end 17) t)
  4427. (goto-char (match-end 0))
  4428. ;; Now look for attributes after prototype:
  4429. (forward-comment (buffer-size))
  4430. (and (looking-at ":[^:]")
  4431. (cperl-find-sub-attrs st-l b1 e1 b)))
  4432. ;; treat attributes without prototype
  4433. (goto-char (match-beginning 17))
  4434. (cperl-find-sub-attrs st-l b1 e1 b))))
  4435. ;; 1+6+2+1+1+6+1=18 extra () before this:
  4436. ;; "\\(\\<sub[ \t\n\f]+\\|[&*$@%]\\)[a-zA-Z0-9_]*'")
  4437. ((match-beginning 19) ; old $abc'efg syntax
  4438. (setq bb (match-end 0))
  4439. ;;;(if (nth 3 state) nil ; in string
  4440. (put-text-property (1- bb) bb 'syntax-table cperl-st-word)
  4441. (goto-char bb))
  4442. ;; 1+6+2+1+1+6+1+1=19 extra () before this:
  4443. ;; "__\\(END\\|DATA\\)__"
  4444. ((match-beginning 20) ; __END__, __DATA__
  4445. (setq bb (match-end 0))
  4446. ;; (put-text-property b (1+ bb) 'syntax-type 'pod) ; Cheat
  4447. (cperl-commentify b bb nil)
  4448. (setq end t))
  4449. ;; "\\\\\\(['`\"($]\\)"
  4450. ((match-beginning 21)
  4451. ;; Trailing backslash; make non-quoting outside string/comment
  4452. (setq bb (match-end 0))
  4453. (goto-char b)
  4454. (skip-chars-backward "\\\\")
  4455. ;;;(setq i2 (= (% (skip-chars-backward "\\\\") 2) -1))
  4456. (cperl-modify-syntax-type b cperl-st-punct)
  4457. (goto-char bb))
  4458. (t (error "Error in regexp of the sniffer")))
  4459. (if (> (point) stop-point)
  4460. (progn
  4461. (if end
  4462. (message "Garbage after __END__/__DATA__ ignored")
  4463. (message "Unbalanced syntax found while scanning")
  4464. (or (car err-l) (setcar err-l b)))
  4465. (goto-char stop-point))))
  4466. (setq cperl-syntax-state (cons state-point state)
  4467. ;; Do not mark syntax as done past tmpend???
  4468. cperl-syntax-done-to (or tmpend (max (point) max)))
  4469. ;;(message "state-at=%s, done-to=%s" state-point cperl-syntax-done-to)
  4470. )
  4471. (if (car err-l) (goto-char (car err-l))
  4472. (or non-inter
  4473. (message "Scanning for \"hard\" Perl constructions... done"))))
  4474. (and (buffer-modified-p)
  4475. (not modified)
  4476. (set-buffer-modified-p nil))
  4477. ;; I do not understand what this is doing here. It breaks font-locking
  4478. ;; because it resets the syntax-table from font-lock-syntax-table to
  4479. ;; cperl-mode-syntax-table.
  4480. ;; (set-syntax-table cperl-mode-syntax-table)
  4481. )
  4482. (list (car err-l) overshoot)))
  4483. (defun cperl-find-pods-heres-region (min max)
  4484. (interactive "r")
  4485. (cperl-find-pods-heres min max))
  4486. (defun cperl-backward-to-noncomment (lim)
  4487. ;; Stops at lim or after non-whitespace that is not in comment
  4488. ;; XXXX Wrongly understands end-of-multiline strings with # as comment
  4489. (let (stop p pr)
  4490. (while (and (not stop) (> (point) (or lim (point-min))))
  4491. (skip-chars-backward " \t\n\f" lim)
  4492. (setq p (point))
  4493. (beginning-of-line)
  4494. (if (memq (setq pr (get-text-property (point) 'syntax-type))
  4495. '(pod here-doc here-doc-delim))
  4496. (progn
  4497. (cperl-unwind-to-safe nil)
  4498. (setq pr (get-text-property (point) 'syntax-type))))
  4499. (or (and (looking-at "^[ \t]*\\(#\\|$\\)")
  4500. (not (memq pr '(string prestring))))
  4501. (progn (cperl-to-comment-or-eol) (bolp))
  4502. (progn
  4503. (skip-chars-backward " \t")
  4504. (if (< p (point)) (goto-char p))
  4505. (setq stop t))))))
  4506. ;; Used only in `cperl-calculate-indent'...
  4507. (defun cperl-block-p () ; Do not C-M-q ! One string contains ";" !
  4508. ;; Positions is before ?\{. Checks whether it starts a block.
  4509. ;; No save-excursion! This is more a distinguisher of a block/hash ref...
  4510. (cperl-backward-to-noncomment (point-min))
  4511. (or (memq (preceding-char) (append ";){}$@&%\C-@" nil)) ; Or label! \C-@ at bobp
  4512. ; Label may be mixed up with `$blah :'
  4513. (save-excursion (cperl-after-label))
  4514. (get-text-property (cperl-1- (point)) 'attrib-group)
  4515. (and (memq (char-syntax (preceding-char)) '(?w ?_))
  4516. (progn
  4517. (backward-sexp)
  4518. ;; sub {BLK}, print {BLK} $data, but NOT `bless', `return', `tr'
  4519. (or (and (looking-at "[a-zA-Z0-9_:]+[ \t\n\f]*[{#]") ; Method call syntax
  4520. (not (looking-at "\\(bless\\|return\\|q[wqrx]?\\|tr\\|[smy]\\)\\>")))
  4521. ;; sub bless::foo {}
  4522. (progn
  4523. (cperl-backward-to-noncomment (point-min))
  4524. (and (eq (preceding-char) ?b)
  4525. (progn
  4526. (forward-sexp -1)
  4527. (looking-at "sub[ \t\n\f#]")))))))))
  4528. ;;; What is the difference of (cperl-after-block-p lim t) and (cperl-block-p)?
  4529. ;;; No save-excursion; condition-case ... In (cperl-block-p) the block
  4530. ;;; may be a part of an in-statement construct, such as
  4531. ;;; ${something()}, print {FH} $data.
  4532. ;;; Moreover, one takes positive approach (looks for else,grep etc)
  4533. ;;; another negative (looks for bless,tr etc)
  4534. (defun cperl-after-block-p (lim &optional pre-block)
  4535. "Return true if the preceding } (if PRE-BLOCK, following {) delimits a block.
  4536. Would not look before LIM. Assumes that LIM is a good place to begin a
  4537. statement. The kind of block we treat here is one after which a new
  4538. statement would start; thus the block in ${func()} does not count."
  4539. (save-excursion
  4540. (condition-case nil
  4541. (progn
  4542. (or pre-block (forward-sexp -1))
  4543. (cperl-backward-to-noncomment lim)
  4544. (or (eq (point) lim)
  4545. ;; if () {} // sub f () {} // sub f :a(') {}
  4546. (eq (preceding-char) ?\) )
  4547. ;; label: {}
  4548. (save-excursion (cperl-after-label))
  4549. ;; sub :attr {}
  4550. (get-text-property (cperl-1- (point)) 'attrib-group)
  4551. (if (memq (char-syntax (preceding-char)) '(?w ?_)) ; else {}
  4552. (save-excursion
  4553. (forward-sexp -1)
  4554. ;; else {} but not else::func {}
  4555. (or (and (looking-at "\\(else\\|continue\\|grep\\|map\\|BEGIN\\|END\\|CHECK\\|INIT\\)\\>")
  4556. (not (looking-at "\\(\\sw\\|_\\)+::")))
  4557. ;; sub f {}
  4558. (progn
  4559. (cperl-backward-to-noncomment lim)
  4560. (and (eq (preceding-char) ?b)
  4561. (progn
  4562. (forward-sexp -1)
  4563. (looking-at "sub[ \t\n\f#]"))))))
  4564. ;; What precedes is not word... XXXX Last statement in sub???
  4565. (cperl-after-expr-p lim))))
  4566. (error nil))))
  4567. (defun cperl-after-expr-p (&optional lim chars test)
  4568. "Return true if the position is good for start of expression.
  4569. TEST is the expression to evaluate at the found position. If absent,
  4570. CHARS is a string that contains good characters to have before us (however,
  4571. `}' is treated \"smartly\" if it is not in the list)."
  4572. (let ((lim (or lim (point-min)))
  4573. stop p pr)
  4574. (cperl-update-syntaxification (point) (point))
  4575. (save-excursion
  4576. (while (and (not stop) (> (point) lim))
  4577. (skip-chars-backward " \t\n\f" lim)
  4578. (setq p (point))
  4579. (beginning-of-line)
  4580. ;;(memq (setq pr (get-text-property (point) 'syntax-type))
  4581. ;; '(pod here-doc here-doc-delim))
  4582. (if (get-text-property (point) 'here-doc-group)
  4583. (progn
  4584. (goto-char
  4585. (cperl-beginning-of-property (point) 'here-doc-group))
  4586. (beginning-of-line 0)))
  4587. (if (get-text-property (point) 'in-pod)
  4588. (progn
  4589. (goto-char
  4590. (cperl-beginning-of-property (point) 'in-pod))
  4591. (beginning-of-line 0)))
  4592. (if (looking-at "^[ \t]*\\(#\\|$\\)") nil ; Only comment, skip
  4593. ;; Else: last iteration, or a label
  4594. (cperl-to-comment-or-eol) ; Will not move past "." after a format
  4595. (skip-chars-backward " \t")
  4596. (if (< p (point)) (goto-char p))
  4597. (setq p (point))
  4598. (if (and (eq (preceding-char) ?:)
  4599. (progn
  4600. (forward-char -1)
  4601. (skip-chars-backward " \t\n\f" lim)
  4602. (memq (char-syntax (preceding-char)) '(?w ?_))))
  4603. (forward-sexp -1) ; Possibly label. Skip it
  4604. (goto-char p)
  4605. (setq stop t))))
  4606. (or (bobp) ; ???? Needed
  4607. (eq (point) lim)
  4608. (looking-at "[ \t]*__\\(END\\|DATA\\)__") ; After this anything goes
  4609. (progn
  4610. (if test (eval test)
  4611. (or (memq (preceding-char) (append (or chars "{;") nil))
  4612. (and (eq (preceding-char) ?\})
  4613. (cperl-after-block-p lim))
  4614. (and (eq (following-char) ?.) ; in format: see comment above
  4615. (eq (get-text-property (point) 'syntax-type)
  4616. 'format)))))))))
  4617. (defun cperl-backward-to-start-of-expr (&optional lim)
  4618. (condition-case nil
  4619. (progn
  4620. (while (and (or (not lim)
  4621. (> (point) lim))
  4622. (not (cperl-after-expr-p lim)))
  4623. (forward-sexp -1)
  4624. ;; May be after $, @, $# etc of a variable
  4625. (skip-chars-backward "$@%#")))
  4626. (error nil)))
  4627. (defun cperl-at-end-of-expr (&optional lim)
  4628. ;; Since the SEXP approach below is very fragile, do some overengineering
  4629. (or (looking-at (concat cperl-maybe-white-and-comment-rex "[;}]"))
  4630. (condition-case nil
  4631. (save-excursion
  4632. ;; If nothing interesting after, does as (forward-sexp -1);
  4633. ;; otherwise fails, or ends at a start of following sexp.
  4634. ;; XXXX PROBLEMS: if what follows (after ";") @FOO, or ${bar}
  4635. ;; may be stuck after @ or $; just put some stupid workaround now:
  4636. (let ((p (point)))
  4637. (forward-sexp 1)
  4638. (forward-sexp -1)
  4639. (while (memq (preceding-char) (append "%&@$*" nil))
  4640. (forward-char -1))
  4641. (or (< (point) p)
  4642. (cperl-after-expr-p lim))))
  4643. (error t))))
  4644. (defun cperl-forward-to-end-of-expr (&optional lim)
  4645. (let ((p (point))))
  4646. (condition-case nil
  4647. (progn
  4648. (while (and (< (point) (or lim (point-max)))
  4649. (not (cperl-at-end-of-expr)))
  4650. (forward-sexp 1)))
  4651. (error nil)))
  4652. (defun cperl-backward-to-start-of-continued-exp (lim)
  4653. (if (memq (preceding-char) (append ")]}\"'`" nil))
  4654. (forward-sexp -1))
  4655. (beginning-of-line)
  4656. (if (<= (point) lim)
  4657. (goto-char (1+ lim)))
  4658. (skip-chars-forward " \t"))
  4659. (defun cperl-after-block-and-statement-beg (lim)
  4660. ;; We assume that we are after ?\}
  4661. (and
  4662. (cperl-after-block-p lim)
  4663. (save-excursion
  4664. (forward-sexp -1)
  4665. (cperl-backward-to-noncomment (point-min))
  4666. (or (bobp)
  4667. (eq (point) lim)
  4668. (not (= (char-syntax (preceding-char)) ?w))
  4669. (progn
  4670. (forward-sexp -1)
  4671. (not
  4672. (looking-at
  4673. "\\(map\\|grep\\|printf?\\|system\\|exec\\|tr\\|s\\)\\>")))))))
  4674. (defun cperl-indent-exp ()
  4675. "Simple variant of indentation of continued-sexp.
  4676. Will not indent comment if it starts at `comment-indent' or looks like
  4677. continuation of the comment on the previous line.
  4678. If `cperl-indent-region-fix-constructs', will improve spacing on
  4679. conditional/loop constructs."
  4680. (interactive)
  4681. (save-excursion
  4682. (let ((tmp-end (point-at-eol)) top done)
  4683. (save-excursion
  4684. (beginning-of-line)
  4685. (while (null done)
  4686. (setq top (point))
  4687. ;; Plan A: if line has an unfinished paren-group, go to end-of-group
  4688. (while (= -1 (nth 0 (parse-partial-sexp (point) tmp-end -1)))
  4689. (setq top (point))) ; Get the outermost parens in line
  4690. (goto-char top)
  4691. (while (< (point) tmp-end)
  4692. (parse-partial-sexp (point) tmp-end nil t) ; To start-sexp or eol
  4693. (or (eolp) (forward-sexp 1)))
  4694. (if (> (point) tmp-end) ; Yes, there an unfinished block
  4695. nil
  4696. (if (eq ?\) (preceding-char))
  4697. (progn ;; Plan B: find by REGEXP block followup this line
  4698. (setq top (point))
  4699. (condition-case nil
  4700. (progn
  4701. (forward-sexp -2)
  4702. (if (eq (following-char) ?$ ) ; for my $var (list)
  4703. (progn
  4704. (forward-sexp -1)
  4705. (if (looking-at "\\(my\\|local\\|our\\)\\>")
  4706. (forward-sexp -1))))
  4707. (if (looking-at
  4708. (concat "\\(\\elsif\\|if\\|unless\\|while\\|until"
  4709. "\\|for\\(each\\)?\\>\\(\\("
  4710. cperl-maybe-white-and-comment-rex
  4711. "\\(my\\|local\\|our\\)\\)?"
  4712. cperl-maybe-white-and-comment-rex
  4713. "\\$[_a-zA-Z0-9]+\\)?\\)\\>"))
  4714. (progn
  4715. (goto-char top)
  4716. (forward-sexp 1)
  4717. (setq top (point)))))
  4718. (error (setq done t)))
  4719. (goto-char top))
  4720. (if (looking-at ; Try Plan C: continuation block
  4721. (concat cperl-maybe-white-and-comment-rex
  4722. "\\<\\(else\\|elsif\|continue\\)\\>"))
  4723. (progn
  4724. (goto-char (match-end 0))
  4725. (setq tmp-end (point-at-eol)))
  4726. (setq done t))))
  4727. (setq tmp-end (point-at-eol)))
  4728. (goto-char tmp-end)
  4729. (setq tmp-end (point-marker)))
  4730. (if cperl-indent-region-fix-constructs
  4731. (cperl-fix-line-spacing tmp-end))
  4732. (cperl-indent-region (point) tmp-end))))
  4733. (defun cperl-fix-line-spacing (&optional end parse-data)
  4734. "Improve whitespace in a conditional/loop construct.
  4735. Returns some position at the last line."
  4736. (interactive)
  4737. (or end
  4738. (setq end (point-max)))
  4739. (let ((ee (point-at-eol))
  4740. (cperl-indent-region-fix-constructs
  4741. (or cperl-indent-region-fix-constructs 1))
  4742. p pp ml have-brace ret)
  4743. (save-excursion
  4744. (beginning-of-line)
  4745. (setq ret (point))
  4746. ;; }? continue
  4747. ;; blah; }
  4748. (if (not
  4749. (or (looking-at "[ \t]*\\(els\\(e\\|if\\)\\|continue\\|if\\|while\\|for\\(each\\)?\\|until\\)")
  4750. (setq have-brace (save-excursion (search-forward "}" ee t)))))
  4751. nil ; Do not need to do anything
  4752. ;; Looking at:
  4753. ;; }
  4754. ;; else
  4755. (if cperl-merge-trailing-else
  4756. (if (looking-at
  4757. "[ \t]*}[ \t]*\n[ \t\n]*\\(els\\(e\\|if\\)\\|continue\\)\\>")
  4758. (progn
  4759. (search-forward "}")
  4760. (setq p (point))
  4761. (skip-chars-forward " \t\n")
  4762. (delete-region p (point))
  4763. (insert (make-string cperl-indent-region-fix-constructs ?\s))
  4764. (beginning-of-line)))
  4765. (if (looking-at "[ \t]*}[ \t]*\\(els\\(e\\|if\\)\\|continue\\)\\>")
  4766. (save-excursion
  4767. (search-forward "}")
  4768. (delete-horizontal-space)
  4769. (insert "\n")
  4770. (setq ret (point))
  4771. (if (cperl-indent-line parse-data)
  4772. (progn
  4773. (cperl-fix-line-spacing end parse-data)
  4774. (setq ret (point)))))))
  4775. ;; Looking at:
  4776. ;; } else
  4777. (if (looking-at "[ \t]*}\\(\t*\\|[ \t][ \t]+\\)\\<\\(els\\(e\\|if\\)\\|continue\\)\\>")
  4778. (progn
  4779. (search-forward "}")
  4780. (delete-horizontal-space)
  4781. (insert (make-string cperl-indent-region-fix-constructs ?\s))
  4782. (beginning-of-line)))
  4783. ;; Looking at:
  4784. ;; else {
  4785. (if (looking-at
  4786. "[ \t]*}?[ \t]*\\<\\(\\els\\(e\\|if\\)\\|continue\\|unless\\|if\\|while\\|for\\(each\\)?\\|until\\)\\>\\(\t*\\|[ \t][ \t]+\\)[^ \t\n#]")
  4787. (progn
  4788. (forward-word 1)
  4789. (delete-horizontal-space)
  4790. (insert (make-string cperl-indent-region-fix-constructs ?\s))
  4791. (beginning-of-line)))
  4792. ;; Looking at:
  4793. ;; foreach my $var
  4794. (if (looking-at
  4795. "[ \t]*\\<for\\(each\\)?[ \t]+\\(my\\|local\\|our\\)\\(\t*\\|[ \t][ \t]+\\)[^ \t\n]")
  4796. (progn
  4797. (forward-word 2)
  4798. (delete-horizontal-space)
  4799. (insert (make-string cperl-indent-region-fix-constructs ?\s))
  4800. (beginning-of-line)))
  4801. ;; Looking at:
  4802. ;; foreach my $var (
  4803. (if (looking-at
  4804. "[ \t]*\\<for\\(each\\)?[ \t]+\\(my\\|local\\|our\\)[ \t]*\\$[_a-zA-Z0-9]+\\(\t*\\|[ \t][ \t]+\\)[^ \t\n#]")
  4805. (progn
  4806. (forward-sexp 3)
  4807. (delete-horizontal-space)
  4808. (insert
  4809. (make-string cperl-indent-region-fix-constructs ?\s))
  4810. (beginning-of-line)))
  4811. ;; Looking at (with or without "}" at start, ending after "({"):
  4812. ;; } foreach my $var () OR {
  4813. (if (looking-at
  4814. "[ \t]*\\(}[ \t]*\\)?\\<\\(\\els\\(e\\|if\\)\\|continue\\|if\\|unless\\|while\\|for\\(each\\)?\\(\\([ \t]+\\(my\\|local\\|our\\)\\)?[ \t]*\\$[_a-zA-Z0-9]+\\)?\\|until\\)\\>\\([ \t]*(\\|[ \t\n]*{\\)\\|[ \t]*{")
  4815. (progn
  4816. (setq ml (match-beginning 8)) ; "(" or "{" after control word
  4817. (re-search-forward "[({]")
  4818. (forward-char -1)
  4819. (setq p (point))
  4820. (if (eq (following-char) ?\( )
  4821. (progn
  4822. (forward-sexp 1)
  4823. (setq pp (point))) ; past parenth-group
  4824. ;; after `else' or nothing
  4825. (if ml ; after `else'
  4826. (skip-chars-backward " \t\n")
  4827. (beginning-of-line))
  4828. (setq pp nil))
  4829. ;; Now after the sexp before the brace
  4830. ;; Multiline expr should be special
  4831. (setq ml (and pp (save-excursion (goto-char p)
  4832. (search-forward "\n" pp t))))
  4833. (if (and (or (not pp) (< pp end)) ; Do not go too far...
  4834. (looking-at "[ \t\n]*{"))
  4835. (progn
  4836. (cond
  4837. ((bolp) ; Were before `{', no if/else/etc
  4838. nil)
  4839. ((looking-at "\\(\t*\\| [ \t]+\\){") ; Not exactly 1 SPACE
  4840. (delete-horizontal-space)
  4841. (if (if ml
  4842. cperl-extra-newline-before-brace-multiline
  4843. cperl-extra-newline-before-brace)
  4844. (progn
  4845. (delete-horizontal-space)
  4846. (insert "\n")
  4847. (setq ret (point))
  4848. (if (cperl-indent-line parse-data)
  4849. (progn
  4850. (cperl-fix-line-spacing end parse-data)
  4851. (setq ret (point)))))
  4852. (insert
  4853. (make-string cperl-indent-region-fix-constructs ?\s))))
  4854. ((and (looking-at "[ \t]*\n")
  4855. (not (if ml
  4856. cperl-extra-newline-before-brace-multiline
  4857. cperl-extra-newline-before-brace)))
  4858. (setq pp (point))
  4859. (skip-chars-forward " \t\n")
  4860. (delete-region pp (point))
  4861. (insert
  4862. (make-string cperl-indent-region-fix-constructs ?\ )))
  4863. ((and (looking-at "[\t ]*{")
  4864. (if ml cperl-extra-newline-before-brace-multiline
  4865. cperl-extra-newline-before-brace))
  4866. (delete-horizontal-space)
  4867. (insert "\n")
  4868. (setq ret (point))
  4869. (if (cperl-indent-line parse-data)
  4870. (progn
  4871. (cperl-fix-line-spacing end parse-data)
  4872. (setq ret (point))))))
  4873. ;; Now we are before `{'
  4874. (if (looking-at "[ \t\n]*{[ \t]*[^ \t\n#]")
  4875. (progn
  4876. (skip-chars-forward " \t\n")
  4877. (setq pp (point))
  4878. (forward-sexp 1)
  4879. (setq p (point))
  4880. (goto-char pp)
  4881. (setq ml (search-forward "\n" p t))
  4882. (if (or cperl-break-one-line-blocks-when-indent ml)
  4883. ;; not good: multi-line BLOCK
  4884. (progn
  4885. (goto-char (1+ pp))
  4886. (delete-horizontal-space)
  4887. (insert "\n")
  4888. (setq ret (point))
  4889. (if (cperl-indent-line parse-data)
  4890. (setq ret (cperl-fix-line-spacing end parse-data)))))))))))
  4891. (beginning-of-line)
  4892. (setq p (point) pp (point-at-eol)) ; May be different from ee.
  4893. ;; Now check whether there is a hanging `}'
  4894. ;; Looking at:
  4895. ;; } blah
  4896. (if (and
  4897. cperl-fix-hanging-brace-when-indent
  4898. have-brace
  4899. (not (looking-at "[ \t]*}[ \t]*\\(\\<\\(els\\(if\\|e\\)\\|continue\\|while\\|until\\)\\>\\|$\\|#\\)"))
  4900. (condition-case nil
  4901. (progn
  4902. (up-list 1)
  4903. (if (and (<= (point) pp)
  4904. (eq (preceding-char) ?\} )
  4905. (cperl-after-block-and-statement-beg (point-min)))
  4906. t
  4907. (goto-char p)
  4908. nil))
  4909. (error nil)))
  4910. (progn
  4911. (forward-char -1)
  4912. (skip-chars-backward " \t")
  4913. (if (bolp)
  4914. ;; `}' was the first thing on the line, insert NL *after* it.
  4915. (progn
  4916. (cperl-indent-line parse-data)
  4917. (search-forward "}")
  4918. (delete-horizontal-space)
  4919. (insert "\n"))
  4920. (delete-horizontal-space)
  4921. (or (eq (preceding-char) ?\;)
  4922. (bolp)
  4923. (and (eq (preceding-char) ?\} )
  4924. (cperl-after-block-p (point-min)))
  4925. (insert ";"))
  4926. (insert "\n")
  4927. (setq ret (point)))
  4928. (if (cperl-indent-line parse-data)
  4929. (setq ret (cperl-fix-line-spacing end parse-data)))
  4930. (beginning-of-line)))))
  4931. ret))
  4932. (defvar cperl-update-start) ; Do not need to make them local
  4933. (defvar cperl-update-end)
  4934. (defun cperl-delay-update-hook (beg end old-len)
  4935. (setq cperl-update-start (min beg (or cperl-update-start (point-max))))
  4936. (setq cperl-update-end (max end (or cperl-update-end (point-min)))))
  4937. (defun cperl-indent-region (start end)
  4938. "Simple variant of indentation of region in CPerl mode.
  4939. Should be slow. Will not indent comment if it starts at `comment-indent'
  4940. or looks like continuation of the comment on the previous line.
  4941. Indents all the lines whose first character is between START and END
  4942. inclusive.
  4943. If `cperl-indent-region-fix-constructs', will improve spacing on
  4944. conditional/loop constructs."
  4945. (interactive "r")
  4946. (cperl-update-syntaxification end end)
  4947. (save-excursion
  4948. (let (cperl-update-start cperl-update-end (h-a-c after-change-functions))
  4949. (let ((indent-info (if cperl-emacs-can-parse
  4950. (list nil nil nil) ; Cannot use '(), since will modify
  4951. nil))
  4952. (pm 0)
  4953. after-change-functions ; Speed it up!
  4954. st comm old-comm-indent new-comm-indent p pp i empty)
  4955. (if h-a-c (add-hook 'after-change-functions 'cperl-delay-update-hook))
  4956. (goto-char start)
  4957. (setq old-comm-indent (and (cperl-to-comment-or-eol)
  4958. (current-column))
  4959. new-comm-indent old-comm-indent)
  4960. (goto-char start)
  4961. (setq end (set-marker (make-marker) end)) ; indentation changes pos
  4962. (or (bolp) (beginning-of-line 2))
  4963. (while (and (<= (point) end) (not (eobp))) ; bol to check start
  4964. (setq st (point))
  4965. (if (or
  4966. (setq empty (looking-at "[ \t]*\n"))
  4967. (and (setq comm (looking-at "[ \t]*#"))
  4968. (or (eq (current-indentation) (or old-comm-indent
  4969. comment-column))
  4970. (setq old-comm-indent nil))))
  4971. (if (and old-comm-indent
  4972. (not empty)
  4973. (= (current-indentation) old-comm-indent)
  4974. (not (eq (get-text-property (point) 'syntax-type) 'pod))
  4975. (not (eq (get-text-property (point) 'syntax-table)
  4976. cperl-st-cfence)))
  4977. (let ((comment-column new-comm-indent))
  4978. (indent-for-comment)))
  4979. (progn
  4980. (setq i (cperl-indent-line indent-info))
  4981. (or comm
  4982. (not i)
  4983. (progn
  4984. (if cperl-indent-region-fix-constructs
  4985. (goto-char (cperl-fix-line-spacing end indent-info)))
  4986. (if (setq old-comm-indent
  4987. (and (cperl-to-comment-or-eol)
  4988. (not (memq (get-text-property (point)
  4989. 'syntax-type)
  4990. '(pod here-doc)))
  4991. (not (eq (get-text-property (point)
  4992. 'syntax-table)
  4993. cperl-st-cfence))
  4994. (current-column)))
  4995. (progn (indent-for-comment)
  4996. (skip-chars-backward " \t")
  4997. (skip-chars-backward "#")
  4998. (setq new-comm-indent (current-column))))))))
  4999. (beginning-of-line 2)))
  5000. ;; Now run the update hooks
  5001. (and after-change-functions
  5002. cperl-update-end
  5003. (save-excursion
  5004. (goto-char cperl-update-end)
  5005. (insert " ")
  5006. (delete-char -1)
  5007. (goto-char cperl-update-start)
  5008. (insert " ")
  5009. (delete-char -1))))))
  5010. ;; Stolen from lisp-mode with a lot of improvements
  5011. (defun cperl-fill-paragraph (&optional justify iteration)
  5012. "Like `fill-paragraph', but handle CPerl comments.
  5013. If any of the current line is a comment, fill the comment or the
  5014. block of it that point is in, preserving the comment's initial
  5015. indentation and initial hashes. Behaves usually outside of comment."
  5016. ;; (interactive "P") ; Only works when called from fill-paragraph. -stef
  5017. (let (;; Non-nil if the current line contains a comment.
  5018. has-comment
  5019. fill-paragraph-function ; do not recurse
  5020. ;; If has-comment, the appropriate fill-prefix for the comment.
  5021. comment-fill-prefix
  5022. ;; Line that contains code and comment (or nil)
  5023. start
  5024. c spaces len dc (comment-column comment-column))
  5025. ;; Figure out what kind of comment we are looking at.
  5026. (save-excursion
  5027. (beginning-of-line)
  5028. (cond
  5029. ;; A line with nothing but a comment on it?
  5030. ((looking-at "[ \t]*#[# \t]*")
  5031. (setq has-comment t
  5032. comment-fill-prefix (buffer-substring (match-beginning 0)
  5033. (match-end 0))))
  5034. ;; A line with some code, followed by a comment? Remember that the
  5035. ;; semi which starts the comment shouldn't be part of a string or
  5036. ;; character.
  5037. ((cperl-to-comment-or-eol)
  5038. (setq has-comment t)
  5039. (looking-at "#+[ \t]*")
  5040. (setq start (point) c (current-column)
  5041. comment-fill-prefix
  5042. (concat (make-string (current-column) ?\s)
  5043. (buffer-substring (match-beginning 0) (match-end 0)))
  5044. spaces (progn (skip-chars-backward " \t")
  5045. (buffer-substring (point) start))
  5046. dc (- c (current-column)) len (- start (point))
  5047. start (point-marker))
  5048. (delete-char len)
  5049. (insert (make-string dc ?-))))) ; Placeholder (to avoid splitting???)
  5050. (if (not has-comment)
  5051. (fill-paragraph justify) ; Do the usual thing outside of comment
  5052. ;; Narrow to include only the comment, and then fill the region.
  5053. (save-restriction
  5054. (narrow-to-region
  5055. ;; Find the first line we should include in the region to fill.
  5056. (if start (progn (beginning-of-line) (point))
  5057. (save-excursion
  5058. (while (and (zerop (forward-line -1))
  5059. (looking-at "^[ \t]*#+[ \t]*[^ \t\n#]")))
  5060. ;; We may have gone to far. Go forward again.
  5061. (or (looking-at "^[ \t]*#+[ \t]*[^ \t\n#]")
  5062. (forward-line 1))
  5063. (point)))
  5064. ;; Find the beginning of the first line past the region to fill.
  5065. (save-excursion
  5066. (while (progn (forward-line 1)
  5067. (looking-at "^[ \t]*#+[ \t]*[^ \t\n#]")))
  5068. (point)))
  5069. ;; Remove existing hashes
  5070. (goto-char (point-min))
  5071. (save-excursion
  5072. (while (progn (forward-line 1) (< (point) (point-max)))
  5073. (skip-chars-forward " \t")
  5074. (if (looking-at "#+")
  5075. (progn
  5076. (if (and (eq (point) (match-beginning 0))
  5077. (not (eq (point) (match-end 0)))) nil
  5078. (error
  5079. "Bug in Emacs: `looking-at' in `narrow-to-region': match-data is garbage"))
  5080. (delete-char (- (match-end 0) (match-beginning 0)))))))
  5081. ;; Lines with only hashes on them can be paragraph boundaries.
  5082. (let ((paragraph-start (concat paragraph-start "\\|^[ \t#]*$"))
  5083. (paragraph-separate (concat paragraph-start "\\|^[ \t#]*$"))
  5084. (fill-prefix comment-fill-prefix))
  5085. (fill-paragraph justify)))
  5086. (if (and start)
  5087. (progn
  5088. (goto-char start)
  5089. (if (> dc 0)
  5090. (progn (delete-char dc) (insert spaces)))
  5091. (if (or (= (current-column) c) iteration) nil
  5092. (setq comment-column c)
  5093. (indent-for-comment)
  5094. ;; Repeat once more, flagging as iteration
  5095. (cperl-fill-paragraph justify t))))))
  5096. t)
  5097. (defun cperl-do-auto-fill ()
  5098. ;; Break out if the line is short enough
  5099. (if (> (save-excursion
  5100. (end-of-line)
  5101. (current-column))
  5102. fill-column)
  5103. (let ((c (save-excursion (beginning-of-line)
  5104. (cperl-to-comment-or-eol) (point)))
  5105. (s (memq (following-char) '(?\s ?\t))) marker)
  5106. (if (>= c (point))
  5107. ;; Don't break line inside code: only inside comment.
  5108. nil
  5109. (setq marker (point-marker))
  5110. (fill-paragraph nil)
  5111. (goto-char marker)
  5112. ;; Is not enough, sometimes marker is a start of line
  5113. (if (bolp) (progn (re-search-forward "#+[ \t]*")
  5114. (goto-char (match-end 0))))
  5115. ;; Following space could have gone:
  5116. (if (or (not s) (memq (following-char) '(?\s ?\t))) nil
  5117. (insert " ")
  5118. (backward-char 1))
  5119. ;; Previous space could have gone:
  5120. (or (memq (preceding-char) '(?\s ?\t)) (insert " "))))))
  5121. (defun cperl-imenu-addback (lst &optional isback name)
  5122. ;; We suppose that the lst is a DAG, unless the first element only
  5123. ;; loops back, and ISBACK is set. Thus this function cannot be
  5124. ;; applied twice without ISBACK set.
  5125. (cond ((not cperl-imenu-addback) lst)
  5126. (t
  5127. (or name
  5128. (setq name "+++BACK+++"))
  5129. (mapc (lambda (elt)
  5130. (if (and (listp elt) (listp (cdr elt)))
  5131. (progn
  5132. ;; In the other order it goes up
  5133. ;; one level only ;-(
  5134. (setcdr elt (cons (cons name lst)
  5135. (cdr elt)))
  5136. (cperl-imenu-addback (cdr elt) t name))))
  5137. (if isback (cdr lst) lst))
  5138. lst)))
  5139. (defun cperl-imenu--create-perl-index (&optional regexp)
  5140. (require 'imenu) ; May be called from TAGS creator
  5141. (let ((index-alist '()) (index-pack-alist '()) (index-pod-alist '())
  5142. (index-unsorted-alist '()) (i-s-f (default-value 'imenu-sort-function))
  5143. (index-meth-alist '()) meth
  5144. packages ends-ranges p marker is-proto
  5145. (prev-pos 0) is-pack index index1 name (end-range 0) package)
  5146. (goto-char (point-min))
  5147. (cperl-update-syntaxification (point-max) (point-max))
  5148. ;; Search for the function
  5149. (progn ;;save-match-data
  5150. (while (re-search-forward
  5151. (or regexp cperl-imenu--function-name-regexp-perl)
  5152. nil t)
  5153. ;; 2=package-group, 5=package-name 8=sub-name
  5154. (cond
  5155. ((and ; Skip some noise if building tags
  5156. (match-beginning 5) ; package name
  5157. ;;(eq (char-after (match-beginning 2)) ?p) ; package
  5158. (not (save-match-data
  5159. (looking-at "[ \t\n]*;")))) ; Plain text word 'package'
  5160. nil)
  5161. ((and
  5162. (or (match-beginning 2)
  5163. (match-beginning 8)) ; package or sub
  5164. ;; Skip if quoted (will not skip multi-line ''-strings :-():
  5165. (null (get-text-property (match-beginning 1) 'syntax-table))
  5166. (null (get-text-property (match-beginning 1) 'syntax-type))
  5167. (null (get-text-property (match-beginning 1) 'in-pod)))
  5168. (setq is-pack (match-beginning 2))
  5169. ;; (if (looking-at "([^()]*)[ \t\n\f]*")
  5170. ;; (goto-char (match-end 0))) ; Messes what follows
  5171. (setq meth nil
  5172. p (point))
  5173. (while (and ends-ranges (>= p (car ends-ranges)))
  5174. ;; delete obsolete entries
  5175. (setq ends-ranges (cdr ends-ranges) packages (cdr packages)))
  5176. (setq package (or (car packages) "")
  5177. end-range (or (car ends-ranges) 0))
  5178. (if is-pack ; doing "package"
  5179. (progn
  5180. (if (match-beginning 5) ; named package
  5181. (setq name (buffer-substring (match-beginning 5)
  5182. (match-end 5))
  5183. name (progn
  5184. (set-text-properties 0 (length name) nil name)
  5185. name)
  5186. package (concat name "::")
  5187. name (concat "package " name))
  5188. ;; Support nameless packages
  5189. (setq name "package;" package ""))
  5190. (setq end-range
  5191. (save-excursion
  5192. (parse-partial-sexp (point) (point-max) -1) (point))
  5193. ends-ranges (cons end-range ends-ranges)
  5194. packages (cons package packages)))
  5195. (setq is-proto
  5196. (or (eq (following-char) ?\;)
  5197. (eq 0 (get-text-property (point) 'attrib-group)))))
  5198. ;; Skip this function name if it is a prototype declaration.
  5199. (if (and is-proto (not is-pack)) nil
  5200. (or is-pack
  5201. (setq name
  5202. (buffer-substring (match-beginning 8) (match-end 8)))
  5203. (set-text-properties 0 (length name) nil name))
  5204. (setq marker (make-marker))
  5205. (set-marker marker (match-end (if is-pack 2 8)))
  5206. (cond (is-pack nil)
  5207. ((string-match "[:']" name)
  5208. (setq meth t))
  5209. ((> p end-range) nil)
  5210. (t
  5211. (setq name (concat package name) meth t)))
  5212. (setq index (cons name marker))
  5213. (if is-pack
  5214. (push index index-pack-alist)
  5215. (push index index-alist))
  5216. (if meth (push index index-meth-alist))
  5217. (push index index-unsorted-alist)))
  5218. ((match-beginning 16) ; POD section
  5219. (setq name (buffer-substring (match-beginning 17) (match-end 17))
  5220. marker (make-marker))
  5221. (set-marker marker (match-beginning 17))
  5222. (set-text-properties 0 (length name) nil name)
  5223. (setq name (concat (make-string
  5224. (* 3 (- (char-after (match-beginning 16)) ?1))
  5225. ?\ )
  5226. name)
  5227. index (cons name marker))
  5228. (setq index1 (cons (concat "=" name) (cdr index)))
  5229. (push index index-pod-alist)
  5230. (push index1 index-unsorted-alist)))))
  5231. (setq index-alist
  5232. (if (default-value 'imenu-sort-function)
  5233. (sort index-alist (default-value 'imenu-sort-function))
  5234. (nreverse index-alist)))
  5235. (and index-pod-alist
  5236. (push (cons "+POD headers+..."
  5237. (nreverse index-pod-alist))
  5238. index-alist))
  5239. (and (or index-pack-alist index-meth-alist)
  5240. (let ((lst index-pack-alist) hier-list pack elt group name)
  5241. ;; Remove "package ", reverse and uniquify.
  5242. (while lst
  5243. (setq elt (car lst) lst (cdr lst) name (substring (car elt) 8))
  5244. (if (assoc name hier-list) nil
  5245. (setq hier-list (cons (cons name (cdr elt)) hier-list))))
  5246. (setq lst index-meth-alist)
  5247. (while lst
  5248. (setq elt (car lst) lst (cdr lst))
  5249. (cond ((string-match "\\(::\\|'\\)[_a-zA-Z0-9]+$" (car elt))
  5250. (setq pack (substring (car elt) 0 (match-beginning 0)))
  5251. (if (setq group (assoc pack hier-list))
  5252. (if (listp (cdr group))
  5253. ;; Have some functions already
  5254. (setcdr group
  5255. (cons (cons (substring
  5256. (car elt)
  5257. (+ 2 (match-beginning 0)))
  5258. (cdr elt))
  5259. (cdr group)))
  5260. (setcdr group (list (cons (substring
  5261. (car elt)
  5262. (+ 2 (match-beginning 0)))
  5263. (cdr elt)))))
  5264. (setq hier-list
  5265. (cons (cons pack
  5266. (list (cons (substring
  5267. (car elt)
  5268. (+ 2 (match-beginning 0)))
  5269. (cdr elt))))
  5270. hier-list))))))
  5271. (push (cons "+Hierarchy+..."
  5272. hier-list)
  5273. index-alist)))
  5274. (and index-pack-alist
  5275. (push (cons "+Packages+..."
  5276. (nreverse index-pack-alist))
  5277. index-alist))
  5278. (and (or index-pack-alist index-pod-alist
  5279. (default-value 'imenu-sort-function))
  5280. index-unsorted-alist
  5281. (push (cons "+Unsorted List+..."
  5282. (nreverse index-unsorted-alist))
  5283. index-alist))
  5284. (cperl-imenu-addback index-alist)))
  5285. ;; Suggested by Mark A. Hershberger
  5286. (defun cperl-outline-level ()
  5287. (looking-at outline-regexp)
  5288. (cond ((not (match-beginning 1)) 0) ; beginning-of-file
  5289. ;;;; 2=package-group, 5=package-name 8=sub-name 16=head-level
  5290. ((match-beginning 2) 0) ; package
  5291. ((match-beginning 8) 1) ; sub
  5292. ((match-beginning 16)
  5293. (- (char-after (match-beginning 16)) ?0)) ; headN ==> N
  5294. (t 5))) ; should not happen
  5295. (defun cperl-windowed-init ()
  5296. "Initialization under windowed version."
  5297. (cond ((featurep 'ps-print)
  5298. (or cperl-faces-init
  5299. (progn
  5300. (and (boundp 'font-lock-multiline)
  5301. (setq cperl-font-lock-multiline t))
  5302. (cperl-init-faces))))
  5303. ((not cperl-faces-init)
  5304. (add-hook 'font-lock-mode-hook
  5305. (function
  5306. (lambda ()
  5307. (if (memq major-mode '(perl-mode cperl-mode))
  5308. (progn
  5309. (or cperl-faces-init (cperl-init-faces)))))))
  5310. (if (fboundp 'eval-after-load)
  5311. (eval-after-load
  5312. "ps-print"
  5313. '(or cperl-faces-init (cperl-init-faces)))))))
  5314. (defvar cperl-font-lock-keywords-1 nil
  5315. "Additional expressions to highlight in Perl mode. Minimal set.")
  5316. (defvar cperl-font-lock-keywords nil
  5317. "Additional expressions to highlight in Perl mode. Default set.")
  5318. (defvar cperl-font-lock-keywords-2 nil
  5319. "Additional expressions to highlight in Perl mode. Maximal set")
  5320. (defun cperl-load-font-lock-keywords ()
  5321. (or cperl-faces-init (cperl-init-faces))
  5322. cperl-font-lock-keywords)
  5323. (defun cperl-load-font-lock-keywords-1 ()
  5324. (or cperl-faces-init (cperl-init-faces))
  5325. cperl-font-lock-keywords-1)
  5326. (defun cperl-load-font-lock-keywords-2 ()
  5327. (or cperl-faces-init (cperl-init-faces))
  5328. cperl-font-lock-keywords-2)
  5329. (defun cperl-init-faces-weak ()
  5330. ;; Allow `cperl-find-pods-heres' to run.
  5331. (or (boundp 'font-lock-constant-face)
  5332. (cperl-force-face font-lock-constant-face
  5333. "Face for constant and label names"))
  5334. (or (boundp 'font-lock-warning-face)
  5335. (cperl-force-face font-lock-warning-face
  5336. "Face for things which should stand out"))
  5337. ;;(setq font-lock-constant-face 'font-lock-constant-face)
  5338. )
  5339. (defun cperl-init-faces ()
  5340. (condition-case errs
  5341. (progn
  5342. (require 'font-lock)
  5343. (and (fboundp 'font-lock-fontify-anchored-keywords)
  5344. (featurep 'font-lock-extra)
  5345. (message "You have an obsolete package `font-lock-extra'. Install `choose-color'."))
  5346. (let (t-font-lock-keywords t-font-lock-keywords-1 font-lock-anchored)
  5347. (if (fboundp 'font-lock-fontify-anchored-keywords)
  5348. (setq font-lock-anchored t))
  5349. (setq
  5350. t-font-lock-keywords
  5351. (list
  5352. `("[ \t]+$" 0 ',cperl-invalid-face t)
  5353. (cons
  5354. (concat
  5355. "\\(^\\|[^$@%&\\]\\)\\<\\("
  5356. (mapconcat
  5357. 'identity
  5358. '("if" "until" "while" "elsif" "else" "unless" "for"
  5359. "foreach" "continue" "exit" "die" "last" "goto" "next"
  5360. "redo" "return" "local" "exec" "sub" "do" "dump" "use" "our"
  5361. "require" "package" "eval" "my" "BEGIN" "END" "CHECK" "INIT")
  5362. "\\|") ; Flow control
  5363. "\\)\\>") 2) ; was "\\)[ \n\t;():,\|&]"
  5364. ; In what follows we use `type' style
  5365. ; for overwritable builtins
  5366. (list
  5367. (concat
  5368. "\\(^\\|[^$@%&\\]\\)\\<\\("
  5369. ;; "CORE" "__FILE__" "__LINE__" "abs" "accept" "alarm"
  5370. ;; "and" "atan2" "bind" "binmode" "bless" "caller"
  5371. ;; "chdir" "chmod" "chown" "chr" "chroot" "close"
  5372. ;; "closedir" "cmp" "connect" "continue" "cos" "crypt"
  5373. ;; "dbmclose" "dbmopen" "die" "dump" "endgrent"
  5374. ;; "endhostent" "endnetent" "endprotoent" "endpwent"
  5375. ;; "endservent" "eof" "eq" "exec" "exit" "exp" "fcntl"
  5376. ;; "fileno" "flock" "fork" "formline" "ge" "getc"
  5377. ;; "getgrent" "getgrgid" "getgrnam" "gethostbyaddr"
  5378. ;; "gethostbyname" "gethostent" "getlogin"
  5379. ;; "getnetbyaddr" "getnetbyname" "getnetent"
  5380. ;; "getpeername" "getpgrp" "getppid" "getpriority"
  5381. ;; "getprotobyname" "getprotobynumber" "getprotoent"
  5382. ;; "getpwent" "getpwnam" "getpwuid" "getservbyname"
  5383. ;; "getservbyport" "getservent" "getsockname"
  5384. ;; "getsockopt" "glob" "gmtime" "gt" "hex" "index" "int"
  5385. ;; "ioctl" "join" "kill" "lc" "lcfirst" "le" "length"
  5386. ;; "link" "listen" "localtime" "lock" "log" "lstat" "lt"
  5387. ;; "mkdir" "msgctl" "msgget" "msgrcv" "msgsnd" "ne"
  5388. ;; "not" "oct" "open" "opendir" "or" "ord" "pack" "pipe"
  5389. ;; "quotemeta" "rand" "read" "readdir" "readline"
  5390. ;; "readlink" "readpipe" "recv" "ref" "rename" "require"
  5391. ;; "reset" "reverse" "rewinddir" "rindex" "rmdir" "seek"
  5392. ;; "seekdir" "select" "semctl" "semget" "semop" "send"
  5393. ;; "setgrent" "sethostent" "setnetent" "setpgrp"
  5394. ;; "setpriority" "setprotoent" "setpwent" "setservent"
  5395. ;; "setsockopt" "shmctl" "shmget" "shmread" "shmwrite"
  5396. ;; "shutdown" "sin" "sleep" "socket" "socketpair"
  5397. ;; "sprintf" "sqrt" "srand" "stat" "substr" "symlink"
  5398. ;; "syscall" "sysopen" "sysread" "system" "syswrite" "tell"
  5399. ;; "telldir" "time" "times" "truncate" "uc" "ucfirst"
  5400. ;; "umask" "unlink" "unpack" "utime" "values" "vec"
  5401. ;; "wait" "waitpid" "wantarray" "warn" "write" "x" "xor"
  5402. "a\\(bs\\|ccept\\|tan2\\|larm\\|nd\\)\\|"
  5403. "b\\(in\\(d\\|mode\\)\\|less\\)\\|"
  5404. "c\\(h\\(r\\(\\|oot\\)\\|dir\\|mod\\|own\\)\\|aller\\|rypt\\|"
  5405. "lose\\(\\|dir\\)\\|mp\\|o\\(s\\|n\\(tinue\\|nect\\)\\)\\)\\|"
  5406. "CORE\\|d\\(ie\\|bm\\(close\\|open\\)\\|ump\\)\\|"
  5407. "e\\(x\\(p\\|it\\|ec\\)\\|q\\|nd\\(p\\(rotoent\\|went\\)\\|"
  5408. "hostent\\|servent\\|netent\\|grent\\)\\|of\\)\\|"
  5409. "f\\(ileno\\|cntl\\|lock\\|or\\(k\\|mline\\)\\)\\|"
  5410. "g\\(t\\|lob\\|mtime\\|e\\(\\|t\\(p\\(pid\\|r\\(iority\\|"
  5411. "oto\\(byn\\(ame\\|umber\\)\\|ent\\)\\)\\|eername\\|w"
  5412. "\\(uid\\|ent\\|nam\\)\\|grp\\)\\|host\\(by\\(addr\\|name\\)\\|"
  5413. "ent\\)\\|s\\(erv\\(by\\(port\\|name\\)\\|ent\\)\\|"
  5414. "ock\\(name\\|opt\\)\\)\\|c\\|login\\|net\\(by\\(addr\\|name\\)\\|"
  5415. "ent\\)\\|gr\\(ent\\|nam\\|gid\\)\\)\\)\\)\\|"
  5416. "hex\\|i\\(n\\(t\\|dex\\)\\|octl\\)\\|join\\|kill\\|"
  5417. "l\\(i\\(sten\\|nk\\)\\|stat\\|c\\(\\|first\\)\\|t\\|e"
  5418. "\\(\\|ngth\\)\\|o\\(c\\(altime\\|k\\)\\|g\\)\\)\\|m\\(sg\\(rcv\\|snd\\|"
  5419. "ctl\\|get\\)\\|kdir\\)\\|n\\(e\\|ot\\)\\|o\\(pen\\(\\|dir\\)\\|"
  5420. "r\\(\\|d\\)\\|ct\\)\\|p\\(ipe\\|ack\\)\\|quotemeta\\|"
  5421. "r\\(index\\|and\\|mdir\\|e\\(quire\\|ad\\(pipe\\|\\|lin"
  5422. "\\(k\\|e\\)\\|dir\\)\\|set\\|cv\\|verse\\|f\\|winddir\\|name"
  5423. "\\)\\)\\|s\\(printf\\|qrt\\|rand\\|tat\\|ubstr\\|e\\(t\\(p\\(r"
  5424. "\\(iority\\|otoent\\)\\|went\\|grp\\)\\|hostent\\|s\\(ervent\\|"
  5425. "ockopt\\)\\|netent\\|grent\\)\\|ek\\(\\|dir\\)\\|lect\\|"
  5426. "m\\(ctl\\|op\\|get\\)\\|nd\\)\\|h\\(utdown\\|m\\(read\\|ctl\\|"
  5427. "write\\|get\\)\\)\\|y\\(s\\(read\\|call\\|open\\|tem\\|write\\)\\|"
  5428. "mlink\\)\\|in\\|leep\\|ocket\\(pair\\|\\)\\)\\|t\\(runcate\\|"
  5429. "ell\\(\\|dir\\)\\|ime\\(\\|s\\)\\)\\|u\\(c\\(\\|first\\)\\|"
  5430. "time\\|mask\\|n\\(pack\\|link\\)\\)\\|v\\(alues\\|ec\\)\\|"
  5431. "w\\(a\\(rn\\|it\\(pid\\|\\)\\|ntarray\\)\\|rite\\)\\|"
  5432. "x\\(\\|or\\)\\|__\\(FILE__\\|LINE__\\|PACKAGE__\\)"
  5433. "\\)\\>") 2 'font-lock-type-face)
  5434. ;; In what follows we use `other' style
  5435. ;; for nonoverwritable builtins
  5436. ;; Somehow 's', 'm' are not auto-generated???
  5437. (list
  5438. (concat
  5439. "\\(^\\|[^$@%&\\]\\)\\<\\("
  5440. ;; "AUTOLOAD" "BEGIN" "CHECK" "DESTROY" "END" "INIT" "__END__" "chomp"
  5441. ;; "chop" "defined" "delete" "do" "each" "else" "elsif"
  5442. ;; "eval" "exists" "for" "foreach" "format" "goto"
  5443. ;; "grep" "if" "keys" "last" "local" "map" "my" "next"
  5444. ;; "no" "our" "package" "pop" "pos" "print" "printf" "push"
  5445. ;; "q" "qq" "qw" "qx" "redo" "return" "scalar" "shift"
  5446. ;; "sort" "splice" "split" "study" "sub" "tie" "tr"
  5447. ;; "undef" "unless" "unshift" "untie" "until" "use"
  5448. ;; "while" "y"
  5449. "AUTOLOAD\\|BEGIN\\|CHECK\\|cho\\(p\\|mp\\)\\|d\\(e\\(fined\\|lete\\)\\|"
  5450. "o\\)\\|DESTROY\\|e\\(ach\\|val\\|xists\\|ls\\(e\\|if\\)\\)\\|"
  5451. "END\\|for\\(\\|each\\|mat\\)\\|g\\(rep\\|oto\\)\\|INIT\\|if\\|keys\\|"
  5452. "l\\(ast\\|ocal\\)\\|m\\(ap\\|y\\)\\|n\\(ext\\|o\\)\\|our\\|"
  5453. "p\\(ackage\\|rint\\(\\|f\\)\\|ush\\|o\\(p\\|s\\)\\)\\|"
  5454. "q\\(\\|q\\|w\\|x\\|r\\)\\|re\\(turn\\|do\\)\\|s\\(pli\\(ce\\|t\\)\\|"
  5455. "calar\\|tudy\\|ub\\|hift\\|ort\\)\\|t\\(r\\|ie\\)\\|"
  5456. "u\\(se\\|n\\(shift\\|ti\\(l\\|e\\)\\|def\\|less\\)\\)\\|"
  5457. "while\\|y\\|__\\(END\\|DATA\\)__" ;__DATA__ added manually
  5458. "\\|[sm]" ; Added manually
  5459. "\\)\\>") 2 'cperl-nonoverridable-face)
  5460. ;; (mapconcat 'identity
  5461. ;; '("#endif" "#else" "#ifdef" "#ifndef" "#if"
  5462. ;; "#include" "#define" "#undef")
  5463. ;; "\\|")
  5464. '("-[rwxoRWXOezsfdlpSbctugkTBMAC]\\>\\([ \t]+_\\>\\)?" 0
  5465. font-lock-function-name-face keep) ; Not very good, triggers at "[a-z]"
  5466. ;; This highlights declarations and definitions differently.
  5467. ;; We do not try to highlight in the case of attributes:
  5468. ;; it is already done by `cperl-find-pods-heres'
  5469. (list (concat "\\<sub"
  5470. cperl-white-and-comment-rex ; whitespace/comments
  5471. "\\([^ \n\t{;()]+\\)" ; 2=name (assume non-anonymous)
  5472. "\\("
  5473. cperl-maybe-white-and-comment-rex ;whitespace/comments?
  5474. "([^()]*)\\)?" ; prototype
  5475. cperl-maybe-white-and-comment-rex ; whitespace/comments?
  5476. "[{;]")
  5477. 2 (if cperl-font-lock-multiline
  5478. '(if (eq (char-after (cperl-1- (match-end 0))) ?\{ )
  5479. 'font-lock-function-name-face
  5480. 'font-lock-variable-name-face)
  5481. ;; need to manually set 'multiline' for older font-locks
  5482. '(progn
  5483. (if (< 1 (count-lines (match-beginning 0)
  5484. (match-end 0)))
  5485. (put-text-property
  5486. (+ 3 (match-beginning 0)) (match-end 0)
  5487. 'syntax-type 'multiline))
  5488. (if (eq (char-after (cperl-1- (match-end 0))) ?\{ )
  5489. 'font-lock-function-name-face
  5490. 'font-lock-variable-name-face))))
  5491. '("\\<\\(package\\|require\\|use\\|import\\|no\\|bootstrap\\)[ \t]+\\([a-zA-z_][a-zA-z_0-9:]*\\)[ \t;]" ; require A if B;
  5492. 2 font-lock-function-name-face)
  5493. '("^[ \t]*format[ \t]+\\([a-zA-z_][a-zA-z_0-9:]*\\)[ \t]*=[ \t]*$"
  5494. 1 font-lock-function-name-face)
  5495. (cond ((featurep 'font-lock-extra)
  5496. '("\\([]}\\\\%@>*&]\\|\\$[a-zA-Z0-9_:]*\\)[ \t]*{[ \t]*\\(-?[a-zA-Z0-9_:]+\\)[ \t]*}"
  5497. (2 font-lock-string-face t)
  5498. (0 '(restart 2 t)))) ; To highlight $a{bc}{ef}
  5499. (font-lock-anchored
  5500. '("\\([]}\\\\%@>*&]\\|\\$[a-zA-Z0-9_:]*\\)[ \t]*{[ \t]*\\(-?[a-zA-Z0-9_:]+\\)[ \t]*}"
  5501. (2 font-lock-string-face t)
  5502. ("\\=[ \t]*{[ \t]*\\(-?[a-zA-Z0-9_:]+\\)[ \t]*}"
  5503. nil nil
  5504. (1 font-lock-string-face t))))
  5505. (t '("\\([]}\\\\%@>*&]\\|\\$[a-zA-Z0-9_:]*\\)[ \t]*{[ \t]*\\(-?[a-zA-Z0-9_:]+\\)[ \t]*}"
  5506. 2 font-lock-string-face t)))
  5507. '("[\[ \t{,(]\\(-?[a-zA-Z0-9_:]+\\)[ \t]*=>" 1
  5508. font-lock-string-face t)
  5509. '("^[ \t]*\\([a-zA-Z0-9_]+[ \t]*:\\)[ \t]*\\($\\|{\\|\\<\\(until\\|while\\|for\\(each\\)?\\|do\\)\\>\\)" 1
  5510. font-lock-constant-face) ; labels
  5511. '("\\<\\(continue\\|next\\|last\\|redo\\|goto\\)\\>[ \t]+\\([a-zA-Z0-9_:]+\\)" ; labels as targets
  5512. 2 font-lock-constant-face)
  5513. ;; Uncomment to get perl-mode-like vars
  5514. ;;; '("[$*]{?\\(\\sw+\\)" 1 font-lock-variable-name-face)
  5515. ;;; '("\\([@%]\\|\\$#\\)\\(\\sw+\\)"
  5516. ;;; (2 (cons font-lock-variable-name-face '(underline))))
  5517. (cond ((featurep 'font-lock-extra)
  5518. '("^[ \t]*\\(my\\|local\\|our\\)[ \t]*\\(([ \t]*\\)?\\([$@%*][a-zA-Z0-9_:]+\\)\\([ \t]*,\\)?"
  5519. (3 font-lock-variable-name-face)
  5520. (4 '(another 4 nil
  5521. ("\\=[ \t]*,[ \t]*\\([$@%*][a-zA-Z0-9_:]+\\)\\([ \t]*,\\)?"
  5522. (1 font-lock-variable-name-face)
  5523. (2 '(restart 2 nil) nil t)))
  5524. nil t))) ; local variables, multiple
  5525. (font-lock-anchored
  5526. ;; 1=my_etc, 2=white? 3=(+white? 4=white? 5=var
  5527. `(,(concat "\\<\\(my\\|local\\|our\\)"
  5528. cperl-maybe-white-and-comment-rex
  5529. "\\(("
  5530. cperl-maybe-white-and-comment-rex
  5531. "\\)?\\([$@%*]\\([a-zA-Z0-9_:]+\\|[^a-zA-Z0-9_]\\)\\)")
  5532. (5 ,(if cperl-font-lock-multiline
  5533. 'font-lock-variable-name-face
  5534. '(progn (setq cperl-font-lock-multiline-start
  5535. (match-beginning 0))
  5536. 'font-lock-variable-name-face)))
  5537. (,(concat "\\="
  5538. cperl-maybe-white-and-comment-rex
  5539. ","
  5540. cperl-maybe-white-and-comment-rex
  5541. "\\([$@%*]\\([a-zA-Z0-9_:]+\\|[^a-zA-Z0-9_]\\)\\)")
  5542. ;; Bug in font-lock: limit is used not only to limit
  5543. ;; searches, but to set the "extend window for
  5544. ;; facification" property. Thus we need to minimize.
  5545. ,(if cperl-font-lock-multiline
  5546. '(if (match-beginning 3)
  5547. (save-excursion
  5548. (goto-char (match-beginning 3))
  5549. (condition-case nil
  5550. (forward-sexp 1)
  5551. (error
  5552. (condition-case nil
  5553. (forward-char 200)
  5554. (error nil)))) ; typeahead
  5555. (1- (point))) ; report limit
  5556. (forward-char -2)) ; disable continued expr
  5557. '(if (match-beginning 3)
  5558. (point-max) ; No limit for continuation
  5559. (forward-char -2))) ; disable continued expr
  5560. ,(if cperl-font-lock-multiline
  5561. nil
  5562. '(progn ; Do at end
  5563. ;; "my" may be already fontified (POD),
  5564. ;; so cperl-font-lock-multiline-start is nil
  5565. (if (or (not cperl-font-lock-multiline-start)
  5566. (> 2 (count-lines
  5567. cperl-font-lock-multiline-start
  5568. (point))))
  5569. nil
  5570. (put-text-property
  5571. (1+ cperl-font-lock-multiline-start) (point)
  5572. 'syntax-type 'multiline))
  5573. (setq cperl-font-lock-multiline-start nil)))
  5574. (3 font-lock-variable-name-face))))
  5575. (t '("^[ \t{}]*\\(my\\|local\\|our\\)[ \t]*\\(([ \t]*\\)?\\([$@%*][a-zA-Z0-9_:]+\\)"
  5576. 3 font-lock-variable-name-face)))
  5577. '("\\<for\\(each\\)?\\([ \t]+\\(my\\|local\\|our\\)\\)?[ \t]*\\(\\$[a-zA-Z_][a-zA-Z_0-9]*\\)[ \t]*("
  5578. 4 font-lock-variable-name-face)
  5579. ;; Avoid $!, and s!!, qq!! etc. when not fontifying syntactically
  5580. '("\\(?:^\\|[^smywqrx$]\\)\\(!\\)" 1 font-lock-negation-char-face)
  5581. '("\\[\\(\\^\\)" 1 font-lock-negation-char-face prepend)))
  5582. (setq
  5583. t-font-lock-keywords-1
  5584. (and (fboundp 'turn-on-font-lock) ; Check for newer font-lock
  5585. ;; not yet as of XEmacs 19.12, works with 21.1.11
  5586. (or
  5587. (not (featurep 'xemacs))
  5588. (string< "21.1.9" emacs-version)
  5589. (and (string< "21.1.10" emacs-version)
  5590. (string< emacs-version "21.1.2")))
  5591. '(
  5592. ("\\(\\([@%]\\|\$#\\)[a-zA-Z_:][a-zA-Z0-9_:]*\\)" 1
  5593. (if (eq (char-after (match-beginning 2)) ?%)
  5594. 'cperl-hash-face
  5595. 'cperl-array-face)
  5596. t) ; arrays and hashes
  5597. ("\\(\\([$@]+\\)[a-zA-Z_:][a-zA-Z0-9_:]*\\)[ \t]*\\([[{]\\)"
  5598. 1
  5599. (if (= (- (match-end 2) (match-beginning 2)) 1)
  5600. (if (eq (char-after (match-beginning 3)) ?{)
  5601. 'cperl-hash-face
  5602. 'cperl-array-face) ; arrays and hashes
  5603. font-lock-variable-name-face) ; Just to put something
  5604. t)
  5605. ("\\(@\\|\\$#\\)\\(\\$+\\([a-zA-Z_:][a-zA-Z0-9_:]*\\|[^ \t\n]\\)\\)"
  5606. (1 cperl-array-face)
  5607. (2 font-lock-variable-name-face))
  5608. ("\\(%\\)\\(\\$+\\([a-zA-Z_:][a-zA-Z0-9_:]*\\|[^ \t\n]\\)\\)"
  5609. (1 cperl-hash-face)
  5610. (2 font-lock-variable-name-face))
  5611. ;;("\\([smy]\\|tr\\)\\([^a-z_A-Z0-9]\\)\\(\\([^\n\\]*||\\)\\)\\2")
  5612. ;;; Too much noise from \s* @s[ and friends
  5613. ;;("\\(\\<\\([msy]\\|tr\\)[ \t]*\\([^ \t\na-zA-Z0-9_]\\)\\|\\(/\\)\\)"
  5614. ;;(3 font-lock-function-name-face t t)
  5615. ;;(4
  5616. ;; (if (cperl-slash-is-regexp)
  5617. ;; font-lock-function-name-face 'default) nil t))
  5618. )))
  5619. (if cperl-highlight-variables-indiscriminately
  5620. (setq t-font-lock-keywords-1
  5621. (append t-font-lock-keywords-1
  5622. (list '("\\([$*]{?\\sw+\\)" 1
  5623. font-lock-variable-name-face)))))
  5624. (setq cperl-font-lock-keywords-1
  5625. (if cperl-syntaxify-by-font-lock
  5626. (cons 'cperl-fontify-update
  5627. t-font-lock-keywords)
  5628. t-font-lock-keywords)
  5629. cperl-font-lock-keywords cperl-font-lock-keywords-1
  5630. cperl-font-lock-keywords-2 (append
  5631. cperl-font-lock-keywords-1
  5632. t-font-lock-keywords-1)))
  5633. (if (fboundp 'ps-print-buffer) (cperl-ps-print-init))
  5634. (if (or (featurep 'choose-color) (featurep 'font-lock-extra))
  5635. (eval ; Avoid a warning
  5636. '(font-lock-require-faces
  5637. (list
  5638. ;; Color-light Color-dark Gray-light Gray-dark Mono
  5639. (list 'font-lock-comment-face
  5640. ["Firebrick" "OrangeRed" "DimGray" "Gray80"]
  5641. nil
  5642. [nil nil t t t]
  5643. [nil nil t t t]
  5644. nil)
  5645. (list 'font-lock-string-face
  5646. ["RosyBrown" "LightSalmon" "Gray50" "LightGray"]
  5647. nil
  5648. nil
  5649. [nil nil t t t]
  5650. nil)
  5651. (list 'font-lock-function-name-face
  5652. (vector
  5653. "Blue" "LightSkyBlue" "Gray50" "LightGray"
  5654. (cdr (assq 'background-color ; if mono
  5655. (frame-parameters))))
  5656. (vector
  5657. nil nil nil nil
  5658. (cdr (assq 'foreground-color ; if mono
  5659. (frame-parameters))))
  5660. [nil nil t t t]
  5661. nil
  5662. nil)
  5663. (list 'font-lock-variable-name-face
  5664. ["DarkGoldenrod" "LightGoldenrod" "DimGray" "Gray90"]
  5665. nil
  5666. [nil nil t t t]
  5667. [nil nil t t t]
  5668. nil)
  5669. (list 'font-lock-type-face
  5670. ["DarkOliveGreen" "PaleGreen" "DimGray" "Gray80"]
  5671. nil
  5672. [nil nil t t t]
  5673. nil
  5674. [nil nil t t t])
  5675. (list 'font-lock-warning-face
  5676. ["Pink" "Red" "Gray50" "LightGray"]
  5677. ["gray20" "gray90"
  5678. "gray80" "gray20"]
  5679. [nil nil t t t]
  5680. nil
  5681. [nil nil t t t]
  5682. )
  5683. (list 'font-lock-constant-face
  5684. ["CadetBlue" "Aquamarine" "Gray50" "LightGray"]
  5685. nil
  5686. [nil nil t t t]
  5687. nil
  5688. [nil nil t t t])
  5689. (list 'cperl-nonoverridable-face
  5690. ["chartreuse3" ("orchid1" "orange")
  5691. nil "Gray80"]
  5692. [nil nil "gray90"]
  5693. [nil nil nil t t]
  5694. [nil nil t t]
  5695. [nil nil t t t])
  5696. (list 'cperl-array-face
  5697. ["blue" "yellow" nil "Gray80"]
  5698. ["lightyellow2" ("navy" "os2blue" "darkgreen")
  5699. "gray90"]
  5700. t
  5701. nil
  5702. nil)
  5703. (list 'cperl-hash-face
  5704. ["red" "red" nil "Gray80"]
  5705. ["lightyellow2" ("navy" "os2blue" "darkgreen")
  5706. "gray90"]
  5707. t
  5708. t
  5709. nil))))
  5710. ;; Do it the dull way, without choose-color
  5711. (defvar cperl-guessed-background nil
  5712. "Display characteristics as guessed by cperl.")
  5713. ;; (or (fboundp 'x-color-defined-p)
  5714. ;; (defalias 'x-color-defined-p
  5715. ;; (cond ((fboundp 'color-defined-p) 'color-defined-p)
  5716. ;; ;; XEmacs >= 19.12
  5717. ;; ((fboundp 'valid-color-name-p) 'valid-color-name-p)
  5718. ;; ;; XEmacs 19.11
  5719. ;; (t 'x-valid-color-name-p))))
  5720. (cperl-force-face font-lock-constant-face
  5721. "Face for constant and label names")
  5722. (cperl-force-face font-lock-variable-name-face
  5723. "Face for variable names")
  5724. (cperl-force-face font-lock-type-face
  5725. "Face for data types")
  5726. (cperl-force-face cperl-nonoverridable-face
  5727. "Face for data types from another group")
  5728. (cperl-force-face font-lock-warning-face
  5729. "Face for things which should stand out")
  5730. (cperl-force-face font-lock-comment-face
  5731. "Face for comments")
  5732. (cperl-force-face font-lock-function-name-face
  5733. "Face for function names")
  5734. (cperl-force-face cperl-hash-face
  5735. "Face for hashes")
  5736. (cperl-force-face cperl-array-face
  5737. "Face for arrays")
  5738. ;;(defvar font-lock-constant-face 'font-lock-constant-face)
  5739. ;;(defvar font-lock-variable-name-face 'font-lock-variable-name-face)
  5740. ;;(or (boundp 'font-lock-type-face)
  5741. ;; (defconst font-lock-type-face
  5742. ;; 'font-lock-type-face
  5743. ;; "Face to use for data types."))
  5744. ;;(or (boundp 'cperl-nonoverridable-face)
  5745. ;; (defconst cperl-nonoverridable-face
  5746. ;; 'cperl-nonoverridable-face
  5747. ;; "Face to use for data types from another group."))
  5748. ;;(if (not (featurep 'xemacs)) nil
  5749. ;; (or (boundp 'font-lock-comment-face)
  5750. ;; (defconst font-lock-comment-face
  5751. ;; 'font-lock-comment-face
  5752. ;; "Face to use for comments."))
  5753. ;; (or (boundp 'font-lock-keyword-face)
  5754. ;; (defconst font-lock-keyword-face
  5755. ;; 'font-lock-keyword-face
  5756. ;; "Face to use for keywords."))
  5757. ;; (or (boundp 'font-lock-function-name-face)
  5758. ;; (defconst font-lock-function-name-face
  5759. ;; 'font-lock-function-name-face
  5760. ;; "Face to use for function names.")))
  5761. (if (and
  5762. (not (cperl-is-face 'cperl-array-face))
  5763. (cperl-is-face 'font-lock-emphasized-face))
  5764. (copy-face 'font-lock-emphasized-face 'cperl-array-face))
  5765. (if (and
  5766. (not (cperl-is-face 'cperl-hash-face))
  5767. (cperl-is-face 'font-lock-other-emphasized-face))
  5768. (copy-face 'font-lock-other-emphasized-face 'cperl-hash-face))
  5769. (if (and
  5770. (not (cperl-is-face 'cperl-nonoverridable-face))
  5771. (cperl-is-face 'font-lock-other-type-face))
  5772. (copy-face 'font-lock-other-type-face 'cperl-nonoverridable-face))
  5773. ;;(or (boundp 'cperl-hash-face)
  5774. ;; (defconst cperl-hash-face
  5775. ;; 'cperl-hash-face
  5776. ;; "Face to use for hashes."))
  5777. ;;(or (boundp 'cperl-array-face)
  5778. ;; (defconst cperl-array-face
  5779. ;; 'cperl-array-face
  5780. ;; "Face to use for arrays."))
  5781. ;; Here we try to guess background
  5782. (let ((background
  5783. (if (boundp 'font-lock-background-mode)
  5784. font-lock-background-mode
  5785. 'light))
  5786. (face-list (and (fboundp 'face-list) (face-list))))
  5787. ;;;; (fset 'cperl-is-face
  5788. ;;;; (cond ((fboundp 'find-face)
  5789. ;;;; (symbol-function 'find-face))
  5790. ;;;; (face-list
  5791. ;;;; (function (lambda (face) (member face face-list))))
  5792. ;;;; (t
  5793. ;;;; (function (lambda (face) (boundp face))))))
  5794. (defvar cperl-guessed-background
  5795. (if (and (boundp 'font-lock-display-type)
  5796. (eq font-lock-display-type 'grayscale))
  5797. 'gray
  5798. background)
  5799. "Background as guessed by CPerl mode")
  5800. (and (not (cperl-is-face 'font-lock-constant-face))
  5801. (cperl-is-face 'font-lock-reference-face)
  5802. (copy-face 'font-lock-reference-face 'font-lock-constant-face))
  5803. (if (cperl-is-face 'font-lock-type-face) nil
  5804. (copy-face 'default 'font-lock-type-face)
  5805. (cond
  5806. ((eq background 'light)
  5807. (set-face-foreground 'font-lock-type-face
  5808. (if (x-color-defined-p "seagreen")
  5809. "seagreen"
  5810. "sea green")))
  5811. ((eq background 'dark)
  5812. (set-face-foreground 'font-lock-type-face
  5813. (if (x-color-defined-p "os2pink")
  5814. "os2pink"
  5815. "pink")))
  5816. (t
  5817. (set-face-background 'font-lock-type-face "gray90"))))
  5818. (if (cperl-is-face 'cperl-nonoverridable-face)
  5819. nil
  5820. (copy-face 'font-lock-type-face 'cperl-nonoverridable-face)
  5821. (cond
  5822. ((eq background 'light)
  5823. (set-face-foreground 'cperl-nonoverridable-face
  5824. (if (x-color-defined-p "chartreuse3")
  5825. "chartreuse3"
  5826. "chartreuse")))
  5827. ((eq background 'dark)
  5828. (set-face-foreground 'cperl-nonoverridable-face
  5829. (if (x-color-defined-p "orchid1")
  5830. "orchid1"
  5831. "orange")))))
  5832. ;;; (if (cperl-is-face 'font-lock-other-emphasized-face) nil
  5833. ;;; (copy-face 'bold-italic 'font-lock-other-emphasized-face)
  5834. ;;; (cond
  5835. ;;; ((eq background 'light)
  5836. ;;; (set-face-background 'font-lock-other-emphasized-face
  5837. ;;; (if (x-color-defined-p "lightyellow2")
  5838. ;;; "lightyellow2"
  5839. ;;; (if (x-color-defined-p "lightyellow")
  5840. ;;; "lightyellow"
  5841. ;;; "light yellow"))))
  5842. ;;; ((eq background 'dark)
  5843. ;;; (set-face-background 'font-lock-other-emphasized-face
  5844. ;;; (if (x-color-defined-p "navy")
  5845. ;;; "navy"
  5846. ;;; (if (x-color-defined-p "darkgreen")
  5847. ;;; "darkgreen"
  5848. ;;; "dark green"))))
  5849. ;;; (t (set-face-background 'font-lock-other-emphasized-face "gray90"))))
  5850. ;;; (if (cperl-is-face 'font-lock-emphasized-face) nil
  5851. ;;; (copy-face 'bold 'font-lock-emphasized-face)
  5852. ;;; (cond
  5853. ;;; ((eq background 'light)
  5854. ;;; (set-face-background 'font-lock-emphasized-face
  5855. ;;; (if (x-color-defined-p "lightyellow2")
  5856. ;;; "lightyellow2"
  5857. ;;; "lightyellow")))
  5858. ;;; ((eq background 'dark)
  5859. ;;; (set-face-background 'font-lock-emphasized-face
  5860. ;;; (if (x-color-defined-p "navy")
  5861. ;;; "navy"
  5862. ;;; (if (x-color-defined-p "darkgreen")
  5863. ;;; "darkgreen"
  5864. ;;; "dark green"))))
  5865. ;;; (t (set-face-background 'font-lock-emphasized-face "gray90"))))
  5866. (if (cperl-is-face 'font-lock-variable-name-face) nil
  5867. (copy-face 'italic 'font-lock-variable-name-face))
  5868. (if (cperl-is-face 'font-lock-constant-face) nil
  5869. (copy-face 'italic 'font-lock-constant-face))))
  5870. (setq cperl-faces-init t))
  5871. (error (message "cperl-init-faces (ignored): %s" errs))))
  5872. (defun cperl-ps-print-init ()
  5873. "Initialization of `ps-print' components for faces used in CPerl."
  5874. (eval-after-load "ps-print"
  5875. '(setq ps-bold-faces
  5876. ;; font-lock-variable-name-face
  5877. ;; font-lock-constant-face
  5878. (append '(cperl-array-face cperl-hash-face)
  5879. ps-bold-faces)
  5880. ps-italic-faces
  5881. ;; font-lock-constant-face
  5882. (append '(cperl-nonoverridable-face cperl-hash-face)
  5883. ps-italic-faces)
  5884. ps-underlined-faces
  5885. ;; font-lock-type-face
  5886. (append '(cperl-array-face cperl-hash-face underline cperl-nonoverridable-face)
  5887. ps-underlined-faces))))
  5888. (defvar ps-print-face-extension-alist)
  5889. (defun cperl-ps-print (&optional file)
  5890. "Pretty-print in CPerl style.
  5891. If optional argument FILE is an empty string, prints to printer, otherwise
  5892. to the file FILE. If FILE is nil, prompts for a file name.
  5893. Style of printout regulated by the variable `cperl-ps-print-face-properties'."
  5894. (interactive)
  5895. (or file
  5896. (setq file (read-from-minibuffer
  5897. "Print to file (if empty - to printer): "
  5898. (concat (buffer-file-name) ".ps")
  5899. nil nil 'file-name-history)))
  5900. (or (> (length file) 0)
  5901. (setq file nil))
  5902. (require 'ps-print) ; To get ps-print-face-extension-alist
  5903. (let ((ps-print-color-p t)
  5904. (ps-print-face-extension-alist ps-print-face-extension-alist))
  5905. (cperl-ps-extend-face-list cperl-ps-print-face-properties)
  5906. (ps-print-buffer-with-faces file)))
  5907. ;;; (defun cperl-ps-print-init ()
  5908. ;;; "Initialization of `ps-print' components for faces used in CPerl."
  5909. ;;; ;; Guard against old versions
  5910. ;;; (defvar ps-underlined-faces nil)
  5911. ;;; (defvar ps-bold-faces nil)
  5912. ;;; (defvar ps-italic-faces nil)
  5913. ;;; (setq ps-bold-faces
  5914. ;;; (append '(font-lock-emphasized-face
  5915. ;;; cperl-array-face
  5916. ;;; font-lock-keyword-face
  5917. ;;; font-lock-variable-name-face
  5918. ;;; font-lock-constant-face
  5919. ;;; font-lock-reference-face
  5920. ;;; font-lock-other-emphasized-face
  5921. ;;; cperl-hash-face)
  5922. ;;; ps-bold-faces))
  5923. ;;; (setq ps-italic-faces
  5924. ;;; (append '(cperl-nonoverridable-face
  5925. ;;; font-lock-constant-face
  5926. ;;; font-lock-reference-face
  5927. ;;; font-lock-other-emphasized-face
  5928. ;;; cperl-hash-face)
  5929. ;;; ps-italic-faces))
  5930. ;;; (setq ps-underlined-faces
  5931. ;;; (append '(font-lock-emphasized-face
  5932. ;;; cperl-array-face
  5933. ;;; font-lock-other-emphasized-face
  5934. ;;; cperl-hash-face
  5935. ;;; cperl-nonoverridable-face font-lock-type-face)
  5936. ;;; ps-underlined-faces))
  5937. ;;; (cons 'font-lock-type-face ps-underlined-faces))
  5938. (if (cperl-enable-font-lock) (cperl-windowed-init))
  5939. (defconst cperl-styles-entries
  5940. '(cperl-indent-level cperl-brace-offset cperl-continued-brace-offset
  5941. cperl-label-offset cperl-extra-newline-before-brace
  5942. cperl-extra-newline-before-brace-multiline
  5943. cperl-merge-trailing-else
  5944. cperl-continued-statement-offset))
  5945. (defconst cperl-style-examples
  5946. "##### Numbers etc are: cperl-indent-level cperl-brace-offset
  5947. ##### cperl-continued-brace-offset cperl-label-offset
  5948. ##### cperl-continued-statement-offset
  5949. ##### cperl-merge-trailing-else cperl-extra-newline-before-brace
  5950. ########### (Do not forget cperl-extra-newline-before-brace-multiline)
  5951. ### CPerl (=GNU - extra-newline-before-brace + merge-trailing-else) 2/0/0/-2/2/t/nil
  5952. if (foo) {
  5953. bar
  5954. baz;
  5955. label:
  5956. {
  5957. boon;
  5958. }
  5959. } else {
  5960. stop;
  5961. }
  5962. ### PerlStyle (=CPerl with 4 as indent) 4/0/0/-4/4/t/nil
  5963. if (foo) {
  5964. bar
  5965. baz;
  5966. label:
  5967. {
  5968. boon;
  5969. }
  5970. } else {
  5971. stop;
  5972. }
  5973. ### GNU 2/0/0/-2/2/nil/t
  5974. if (foo)
  5975. {
  5976. bar
  5977. baz;
  5978. label:
  5979. {
  5980. boon;
  5981. }
  5982. }
  5983. else
  5984. {
  5985. stop;
  5986. }
  5987. ### C++ (=PerlStyle with braces aligned with control words) 4/0/-4/-4/4/nil/t
  5988. if (foo)
  5989. {
  5990. bar
  5991. baz;
  5992. label:
  5993. {
  5994. boon;
  5995. }
  5996. }
  5997. else
  5998. {
  5999. stop;
  6000. }
  6001. ### BSD (=C++, but will not change preexisting merge-trailing-else
  6002. ### and extra-newline-before-brace ) 4/0/-4/-4/4
  6003. if (foo)
  6004. {
  6005. bar
  6006. baz;
  6007. label:
  6008. {
  6009. boon;
  6010. }
  6011. }
  6012. else
  6013. {
  6014. stop;
  6015. }
  6016. ### K&R (=C++ with indent 5 - merge-trailing-else, but will not
  6017. ### change preexisting extra-newline-before-brace) 5/0/-5/-5/5/nil
  6018. if (foo)
  6019. {
  6020. bar
  6021. baz;
  6022. label:
  6023. {
  6024. boon;
  6025. }
  6026. }
  6027. else
  6028. {
  6029. stop;
  6030. }
  6031. ### Whitesmith (=PerlStyle, but will not change preexisting
  6032. ### extra-newline-before-brace and merge-trailing-else) 4/0/0/-4/4
  6033. if (foo)
  6034. {
  6035. bar
  6036. baz;
  6037. label:
  6038. {
  6039. boon;
  6040. }
  6041. }
  6042. else
  6043. {
  6044. stop;
  6045. }
  6046. "
  6047. "Examples of if/else with different indent styles (with v4.23).")
  6048. (defconst cperl-style-alist
  6049. '(("CPerl" ;; =GNU - extra-newline-before-brace + cperl-merge-trailing-else
  6050. (cperl-indent-level . 2)
  6051. (cperl-brace-offset . 0)
  6052. (cperl-continued-brace-offset . 0)
  6053. (cperl-label-offset . -2)
  6054. (cperl-continued-statement-offset . 2)
  6055. (cperl-extra-newline-before-brace . nil)
  6056. (cperl-extra-newline-before-brace-multiline . nil)
  6057. (cperl-merge-trailing-else . t))
  6058. ("PerlStyle" ; CPerl with 4 as indent
  6059. (cperl-indent-level . 4)
  6060. (cperl-brace-offset . 0)
  6061. (cperl-continued-brace-offset . 0)
  6062. (cperl-label-offset . -4)
  6063. (cperl-continued-statement-offset . 4)
  6064. (cperl-extra-newline-before-brace . nil)
  6065. (cperl-extra-newline-before-brace-multiline . nil)
  6066. (cperl-merge-trailing-else . t))
  6067. ("GNU"
  6068. (cperl-indent-level . 2)
  6069. (cperl-brace-offset . 0)
  6070. (cperl-continued-brace-offset . 0)
  6071. (cperl-label-offset . -2)
  6072. (cperl-continued-statement-offset . 2)
  6073. (cperl-extra-newline-before-brace . t)
  6074. (cperl-extra-newline-before-brace-multiline . t)
  6075. (cperl-merge-trailing-else . nil))
  6076. ("K&R"
  6077. (cperl-indent-level . 5)
  6078. (cperl-brace-offset . 0)
  6079. (cperl-continued-brace-offset . -5)
  6080. (cperl-label-offset . -5)
  6081. (cperl-continued-statement-offset . 5)
  6082. ;;(cperl-extra-newline-before-brace . nil) ; ???
  6083. ;;(cperl-extra-newline-before-brace-multiline . nil)
  6084. (cperl-merge-trailing-else . nil))
  6085. ("BSD"
  6086. (cperl-indent-level . 4)
  6087. (cperl-brace-offset . 0)
  6088. (cperl-continued-brace-offset . -4)
  6089. (cperl-label-offset . -4)
  6090. (cperl-continued-statement-offset . 4)
  6091. ;;(cperl-extra-newline-before-brace . nil) ; ???
  6092. ;;(cperl-extra-newline-before-brace-multiline . nil)
  6093. ;;(cperl-merge-trailing-else . nil) ; ???
  6094. )
  6095. ("C++"
  6096. (cperl-indent-level . 4)
  6097. (cperl-brace-offset . 0)
  6098. (cperl-continued-brace-offset . -4)
  6099. (cperl-label-offset . -4)
  6100. (cperl-continued-statement-offset . 4)
  6101. (cperl-extra-newline-before-brace . t)
  6102. (cperl-extra-newline-before-brace-multiline . t)
  6103. (cperl-merge-trailing-else . nil))
  6104. ("Whitesmith"
  6105. (cperl-indent-level . 4)
  6106. (cperl-brace-offset . 0)
  6107. (cperl-continued-brace-offset . 0)
  6108. (cperl-label-offset . -4)
  6109. (cperl-continued-statement-offset . 4)
  6110. ;;(cperl-extra-newline-before-brace . nil) ; ???
  6111. ;;(cperl-extra-newline-before-brace-multiline . nil)
  6112. ;;(cperl-merge-trailing-else . nil) ; ???
  6113. )
  6114. ("Current"))
  6115. "List of variables to set to get a particular indentation style.
  6116. Should be used via `cperl-set-style' or via Perl menu.
  6117. See examples in `cperl-style-examples'.")
  6118. (defun cperl-set-style (style)
  6119. "Set CPerl mode variables to use one of several different indentation styles.
  6120. The arguments are a string representing the desired style.
  6121. The list of styles is in `cperl-style-alist', available styles
  6122. are CPerl, PerlStyle, GNU, K&R, BSD, C++ and Whitesmith.
  6123. The current value of style is memorized (unless there is a memorized
  6124. data already), may be restored by `cperl-set-style-back'.
  6125. Choosing \"Current\" style will not change style, so this may be used for
  6126. side-effect of memorizing only. Examples in `cperl-style-examples'."
  6127. (interactive
  6128. (let ((list (mapcar (function (lambda (elt) (list (car elt))))
  6129. cperl-style-alist)))
  6130. (list (completing-read "Enter style: " list nil 'insist))))
  6131. (or cperl-old-style
  6132. (setq cperl-old-style
  6133. (mapcar (function
  6134. (lambda (name)
  6135. (cons name (eval name))))
  6136. cperl-styles-entries)))
  6137. (let ((style (cdr (assoc style cperl-style-alist))) setting str sym)
  6138. (while style
  6139. (setq setting (car style) style (cdr style))
  6140. (set (car setting) (cdr setting)))))
  6141. (defun cperl-set-style-back ()
  6142. "Restore a style memorized by `cperl-set-style'."
  6143. (interactive)
  6144. (or cperl-old-style (error "The style was not changed"))
  6145. (let (setting)
  6146. (while cperl-old-style
  6147. (setq setting (car cperl-old-style)
  6148. cperl-old-style (cdr cperl-old-style))
  6149. (set (car setting) (cdr setting)))))
  6150. (defun cperl-check-syntax ()
  6151. (interactive)
  6152. (require 'mode-compile)
  6153. (let ((perl-dbg-flags (concat cperl-extra-perl-args " -wc")))
  6154. (eval '(mode-compile)))) ; Avoid a warning
  6155. (defun cperl-info-buffer (type)
  6156. ;; Returns buffer with documentation. Creates if missing.
  6157. ;; If TYPE, this vars buffer.
  6158. ;; Special care is taken to not stomp over an existing info buffer
  6159. (let* ((bname (if type "*info-perl-var*" "*info-perl*"))
  6160. (info (get-buffer bname))
  6161. (oldbuf (get-buffer "*info*")))
  6162. (if info info
  6163. (save-window-excursion
  6164. ;; Get Info running
  6165. (require 'info)
  6166. (cond (oldbuf
  6167. (set-buffer oldbuf)
  6168. (rename-buffer "*info-perl-tmp*")))
  6169. (save-window-excursion
  6170. (info))
  6171. (Info-find-node cperl-info-page (if type "perlvar" "perlfunc"))
  6172. (set-buffer "*info*")
  6173. (rename-buffer bname)
  6174. (cond (oldbuf
  6175. (set-buffer "*info-perl-tmp*")
  6176. (rename-buffer "*info*")
  6177. (set-buffer bname)))
  6178. (make-local-variable 'window-min-height)
  6179. (setq window-min-height 2)
  6180. (current-buffer)))))
  6181. (defun cperl-word-at-point (&optional p)
  6182. "Return the word at point or at P."
  6183. (save-excursion
  6184. (if p (goto-char p))
  6185. (or (cperl-word-at-point-hard)
  6186. (progn
  6187. (require 'etags)
  6188. (funcall (or (and (boundp 'find-tag-default-function)
  6189. find-tag-default-function)
  6190. (get major-mode 'find-tag-default-function)
  6191. ;; XEmacs 19.12 has `find-tag-default-hook'; it is
  6192. ;; automatically used within `find-tag-default':
  6193. 'find-tag-default))))))
  6194. (defun cperl-info-on-command (command)
  6195. "Show documentation for Perl command COMMAND in other window.
  6196. If perl-info buffer is shown in some frame, uses this frame.
  6197. Customized by setting variables `cperl-shrink-wrap-info-frame',
  6198. `cperl-max-help-size'."
  6199. (interactive
  6200. (let* ((default (cperl-word-at-point))
  6201. (read (read-string
  6202. (format "Find doc for Perl function (default %s): "
  6203. default))))
  6204. (list (if (equal read "")
  6205. default
  6206. read))))
  6207. (let ((buffer (current-buffer))
  6208. (cmd-desc (concat "^" (regexp-quote command) "[^a-zA-Z_0-9]")) ; "tr///"
  6209. pos isvar height iniheight frheight buf win fr1 fr2 iniwin not-loner
  6210. max-height char-height buf-list)
  6211. (if (string-match "^-[a-zA-Z]$" command)
  6212. (setq cmd-desc "^-X[ \t\n]"))
  6213. (setq isvar (string-match "^[$@%]" command)
  6214. buf (cperl-info-buffer isvar)
  6215. iniwin (selected-window)
  6216. fr1 (window-frame iniwin))
  6217. (set-buffer buf)
  6218. (goto-char (point-min))
  6219. (or isvar
  6220. (progn (re-search-forward "^-X[ \t\n]")
  6221. (forward-line -1)))
  6222. (if (re-search-forward cmd-desc nil t)
  6223. (progn
  6224. ;; Go back to beginning of the group (ex, for qq)
  6225. (if (re-search-backward "^[ \t\n\f]")
  6226. (forward-line 1))
  6227. (beginning-of-line)
  6228. ;; Get some of
  6229. (setq pos (point)
  6230. buf-list (list buf "*info-perl-var*" "*info-perl*"))
  6231. (while (and (not win) buf-list)
  6232. (setq win (get-buffer-window (car buf-list) t))
  6233. (setq buf-list (cdr buf-list)))
  6234. (or (not win)
  6235. (eq (window-buffer win) buf)
  6236. (set-window-buffer win buf))
  6237. (and win (setq fr2 (window-frame win)))
  6238. (if (or (not fr2) (eq fr1 fr2))
  6239. (pop-to-buffer buf)
  6240. (special-display-popup-frame buf) ; Make it visible
  6241. (select-window win))
  6242. (goto-char pos) ; Needed (?!).
  6243. ;; Resize
  6244. (setq iniheight (window-height)
  6245. frheight (frame-height)
  6246. not-loner (< iniheight (1- frheight))) ; Are not alone
  6247. (cond ((if not-loner cperl-max-help-size
  6248. cperl-shrink-wrap-info-frame)
  6249. (setq height
  6250. (+ 2
  6251. (count-lines
  6252. pos
  6253. (save-excursion
  6254. (if (re-search-forward
  6255. "^[ \t][^\n]*\n+\\([^ \t\n\f]\\|\\'\\)" nil t)
  6256. (match-beginning 0) (point-max)))))
  6257. max-height
  6258. (if not-loner
  6259. (/ (* (- frheight 3) cperl-max-help-size) 100)
  6260. (setq char-height (frame-char-height))
  6261. ;; Non-functioning under OS/2:
  6262. (if (eq char-height 1) (setq char-height 18))
  6263. ;; Title, menubar, + 2 for slack
  6264. (- (/ (display-pixel-height) char-height) 4)))
  6265. (if (> height max-height) (setq height max-height))
  6266. ;;(message "was %s doing %s" iniheight height)
  6267. (if not-loner
  6268. (enlarge-window (- height iniheight))
  6269. (set-frame-height (window-frame win) (1+ height)))))
  6270. (set-window-start (selected-window) pos))
  6271. (message "No entry for %s found." command))
  6272. ;;(pop-to-buffer buffer)
  6273. (select-window iniwin)))
  6274. (defun cperl-info-on-current-command ()
  6275. "Show documentation for Perl command at point in other window."
  6276. (interactive)
  6277. (cperl-info-on-command (cperl-word-at-point)))
  6278. (defun cperl-imenu-info-imenu-search ()
  6279. (if (looking-at "^-X[ \t\n]") nil
  6280. (re-search-backward
  6281. "^\n\\([-a-zA-Z_]+\\)[ \t\n]")
  6282. (forward-line 1)))
  6283. (defun cperl-imenu-info-imenu-name ()
  6284. (buffer-substring
  6285. (match-beginning 1) (match-end 1)))
  6286. (defun cperl-imenu-on-info ()
  6287. "Shows imenu for Perl Info Buffer.
  6288. Opens Perl Info buffer if needed."
  6289. (interactive)
  6290. (let* ((buffer (current-buffer))
  6291. imenu-create-index-function
  6292. imenu-prev-index-position-function
  6293. imenu-extract-index-name-function
  6294. (index-item (save-restriction
  6295. (save-window-excursion
  6296. (set-buffer (cperl-info-buffer nil))
  6297. (setq imenu-create-index-function
  6298. 'imenu-default-create-index-function
  6299. imenu-prev-index-position-function
  6300. 'cperl-imenu-info-imenu-search
  6301. imenu-extract-index-name-function
  6302. 'cperl-imenu-info-imenu-name)
  6303. (imenu-choose-buffer-index)))))
  6304. (and index-item
  6305. (progn
  6306. (push-mark)
  6307. (pop-to-buffer "*info-perl*")
  6308. (cond
  6309. ((markerp (cdr index-item))
  6310. (goto-char (marker-position (cdr index-item))))
  6311. (t
  6312. (goto-char (cdr index-item))))
  6313. (set-window-start (selected-window) (point))
  6314. (pop-to-buffer buffer)))))
  6315. (defun cperl-lineup (beg end &optional step minshift)
  6316. "Lineup construction in a region.
  6317. Beginning of region should be at the start of a construction.
  6318. All first occurrences of this construction in the lines that are
  6319. partially contained in the region are lined up at the same column.
  6320. MINSHIFT is the minimal amount of space to insert before the construction.
  6321. STEP is the tabwidth to position constructions.
  6322. If STEP is nil, `cperl-lineup-step' will be used
  6323. \(or `cperl-indent-level', if `cperl-lineup-step' is nil).
  6324. Will not move the position at the start to the left."
  6325. (interactive "r")
  6326. (let (search col tcol seen b)
  6327. (save-excursion
  6328. (goto-char end)
  6329. (end-of-line)
  6330. (setq end (point-marker))
  6331. (goto-char beg)
  6332. (skip-chars-forward " \t\f")
  6333. (setq beg (point-marker))
  6334. (indent-region beg end nil)
  6335. (goto-char beg)
  6336. (setq col (current-column))
  6337. (if (looking-at "[a-zA-Z0-9_]")
  6338. (if (looking-at "\\<[a-zA-Z0-9_]+\\>")
  6339. (setq search
  6340. (concat "\\<"
  6341. (regexp-quote
  6342. (buffer-substring (match-beginning 0)
  6343. (match-end 0))) "\\>"))
  6344. (error "Cannot line up in a middle of the word"))
  6345. (if (looking-at "$")
  6346. (error "Cannot line up end of line"))
  6347. (setq search (regexp-quote (char-to-string (following-char)))))
  6348. (setq step (or step cperl-lineup-step cperl-indent-level))
  6349. (or minshift (setq minshift 1))
  6350. (while (progn
  6351. (beginning-of-line 2)
  6352. (and (< (point) end)
  6353. (re-search-forward search end t)
  6354. (goto-char (match-beginning 0))))
  6355. (setq tcol (current-column) seen t)
  6356. (if (> tcol col) (setq col tcol)))
  6357. (or seen
  6358. (error "The construction to line up occurred only once"))
  6359. (goto-char beg)
  6360. (setq col (+ col minshift))
  6361. (if (/= (% col step) 0) (setq step (* step (1+ (/ col step)))))
  6362. (while
  6363. (progn
  6364. (cperl-make-indent col)
  6365. (beginning-of-line 2)
  6366. (and (< (point) end)
  6367. (re-search-forward search end t)
  6368. (goto-char (match-beginning 0)))))))) ; No body
  6369. (defun cperl-etags (&optional add all files) ;; NOT USED???
  6370. "Run etags with appropriate options for Perl files.
  6371. If optional argument ALL is `recursive', will process Perl files
  6372. in subdirectories too."
  6373. (interactive)
  6374. (let ((cmd "etags")
  6375. (args '("-l" "none" "-r"
  6376. ;; 1=fullname 2=package? 3=name 4=proto? 5=attrs? (VERY APPROX!)
  6377. "/\\<sub[ \\t]+\\(\\([a-zA-Z0-9:_]*::\\)?\\([a-zA-Z0-9_]+\\)\\)[ \\t]*\\(([^()]*)[ \t]*\\)?\\([ \t]*:[^#{;]*\\)?\\([{#]\\|$\\)/\\3/"
  6378. "-r"
  6379. "/\\<package[ \\t]+\\(\\([a-zA-Z0-9:_]*::\\)?\\([a-zA-Z0-9_]+\\)\\)[ \\t]*\\([#;]\\|$\\)/\\1/"
  6380. "-r"
  6381. "/\\<\\(package\\)[ \\t]*;/\\1;/"))
  6382. res)
  6383. (if add (setq args (cons "-a" args)))
  6384. (or files (setq files (list buffer-file-name)))
  6385. (cond
  6386. ((eq all 'recursive)
  6387. ;;(error "Not implemented: recursive")
  6388. (setq args (append (list "-e"
  6389. "sub wanted {push @ARGV, $File::Find::name if /\\.[pP][Llm]$/}
  6390. use File::Find;
  6391. find(\\&wanted, '.');
  6392. exec @ARGV;"
  6393. cmd) args)
  6394. cmd "perl"))
  6395. (all
  6396. ;;(error "Not implemented: all")
  6397. (setq args (append (list "-e"
  6398. "push @ARGV, <*.PL *.pl *.pm>;
  6399. exec @ARGV;"
  6400. cmd) args)
  6401. cmd "perl"))
  6402. (t
  6403. (setq args (append args files))))
  6404. (setq res (apply 'call-process cmd nil nil nil args))
  6405. (or (eq res 0)
  6406. (message "etags returned \"%s\"" res))))
  6407. (defun cperl-toggle-auto-newline ()
  6408. "Toggle the state of `cperl-auto-newline'."
  6409. (interactive)
  6410. (setq cperl-auto-newline (not cperl-auto-newline))
  6411. (message "Newlines will %sbe auto-inserted now."
  6412. (if cperl-auto-newline "" "not ")))
  6413. (defun cperl-toggle-abbrev ()
  6414. "Toggle the state of automatic keyword expansion in CPerl mode."
  6415. (interactive)
  6416. (abbrev-mode (if abbrev-mode 0 1))
  6417. (message "Perl control structure will %sbe auto-inserted now."
  6418. (if abbrev-mode "" "not ")))
  6419. (defun cperl-toggle-electric ()
  6420. "Toggle the state of parentheses doubling in CPerl mode."
  6421. (interactive)
  6422. (setq cperl-electric-parens (if (cperl-val 'cperl-electric-parens) 'null t))
  6423. (message "Parentheses will %sbe auto-doubled now."
  6424. (if (cperl-val 'cperl-electric-parens) "" "not ")))
  6425. (defun cperl-toggle-autohelp ()
  6426. "Toggle the state of Auto-Help on Perl constructs (put in the message area).
  6427. Delay of auto-help controlled by `cperl-lazy-help-time'."
  6428. (interactive)
  6429. (if (fboundp 'run-with-idle-timer)
  6430. (progn
  6431. (if cperl-lazy-installed
  6432. (cperl-lazy-unstall)
  6433. (cperl-lazy-install))
  6434. (message "Perl help messages will %sbe automatically shown now."
  6435. (if cperl-lazy-installed "" "not ")))
  6436. (message "Cannot automatically show Perl help messages - run-with-idle-timer missing.")))
  6437. (defun cperl-toggle-construct-fix ()
  6438. "Toggle whether `indent-region'/`indent-sexp' fix whitespace too."
  6439. (interactive)
  6440. (setq cperl-indent-region-fix-constructs
  6441. (if cperl-indent-region-fix-constructs
  6442. nil
  6443. 1))
  6444. (message "indent-region/indent-sexp will %sbe automatically fix whitespace."
  6445. (if cperl-indent-region-fix-constructs "" "not ")))
  6446. (defun cperl-toggle-set-debug-unwind (arg &optional backtrace)
  6447. "Toggle (or, with numeric argument, set) debugging state of syntaxification.
  6448. Nonpositive numeric argument disables debugging messages. The message
  6449. summarizes which regions it was decided to rescan for syntactic constructs.
  6450. The message looks like this:
  6451. Syxify req=123..138 actual=101..146 done-to: 112=>146 statepos: 73=>117
  6452. Numbers are character positions in the buffer. REQ provides the range to
  6453. rescan requested by `font-lock'. ACTUAL is the range actually resyntaxified;
  6454. for correct operation it should start and end outside any special syntactic
  6455. construct. DONE-TO and STATEPOS indicate changes to internal caches maintained
  6456. by CPerl."
  6457. (interactive "P")
  6458. (or arg
  6459. (setq arg (if (eq cperl-syntaxify-by-font-lock
  6460. (if backtrace 'backtrace 'message)) 0 1)))
  6461. (setq arg (if (> arg 0) (if backtrace 'backtrace 'message) t))
  6462. (setq cperl-syntaxify-by-font-lock arg)
  6463. (message "Debugging messages of syntax unwind %sabled."
  6464. (if (eq arg t) "dis" "en")))
  6465. ;;;; Tags file creation.
  6466. (defvar cperl-tmp-buffer " *cperl-tmp*")
  6467. (defun cperl-setup-tmp-buf ()
  6468. (set-buffer (get-buffer-create cperl-tmp-buffer))
  6469. (set-syntax-table cperl-mode-syntax-table)
  6470. (buffer-disable-undo)
  6471. (auto-fill-mode 0)
  6472. (if cperl-use-syntax-table-text-property-for-tags
  6473. (progn
  6474. (make-local-variable 'parse-sexp-lookup-properties)
  6475. ;; Do not introduce variable if not needed, we check it!
  6476. (set 'parse-sexp-lookup-properties t))))
  6477. ;; Copied from imenu-example--name-and-position.
  6478. (defvar imenu-use-markers)
  6479. (defun cperl-imenu-name-and-position ()
  6480. "Return the current/previous sexp and its (beginning) location.
  6481. Does not move point."
  6482. (save-excursion
  6483. (forward-sexp -1)
  6484. (let ((beg (if imenu-use-markers (point-marker) (point)))
  6485. (end (progn (forward-sexp) (point))))
  6486. (cons (buffer-substring beg end)
  6487. beg))))
  6488. (defun cperl-xsub-scan ()
  6489. (require 'imenu)
  6490. (let ((index-alist '())
  6491. (prev-pos 0) index index1 name package prefix)
  6492. (goto-char (point-min))
  6493. ;; Search for the function
  6494. (progn ;;save-match-data
  6495. (while (re-search-forward
  6496. "^\\([ \t]*MODULE\\>[^\n]*\\<PACKAGE[ \t]*=[ \t]*\\([a-zA-Z_][a-zA-Z_0-9:]*\\)\\>\\|\\([a-zA-Z_][a-zA-Z_0-9]*\\)(\\|[ \t]*BOOT:\\)"
  6497. nil t)
  6498. (cond
  6499. ((match-beginning 2) ; SECTION
  6500. (setq package (buffer-substring (match-beginning 2) (match-end 2)))
  6501. (goto-char (match-beginning 0))
  6502. (skip-chars-forward " \t")
  6503. (forward-char 1)
  6504. (if (looking-at "[^\n]*\\<PREFIX[ \t]*=[ \t]*\\([a-zA-Z_][a-zA-Z_0-9]*\\)\\>")
  6505. (setq prefix (buffer-substring (match-beginning 1) (match-end 1)))
  6506. (setq prefix nil)))
  6507. ((not package) nil) ; C language section
  6508. ((match-beginning 3) ; XSUB
  6509. (goto-char (1+ (match-beginning 3)))
  6510. (setq index (cperl-imenu-name-and-position))
  6511. (setq name (buffer-substring (match-beginning 3) (match-end 3)))
  6512. (if (and prefix (string-match (concat "^" prefix) name))
  6513. (setq name (substring name (length prefix))))
  6514. (cond ((string-match "::" name) nil)
  6515. (t
  6516. (setq index1 (cons (concat package "::" name) (cdr index)))
  6517. (push index1 index-alist)))
  6518. (setcar index name)
  6519. (push index index-alist))
  6520. (t ; BOOT: section
  6521. ;; (beginning-of-line)
  6522. (setq index (cperl-imenu-name-and-position))
  6523. (setcar index (concat package "::BOOT:"))
  6524. (push index index-alist)))))
  6525. index-alist))
  6526. (defvar cperl-unreadable-ok nil)
  6527. (defun cperl-find-tags (ifile xs topdir)
  6528. (let ((b (get-buffer cperl-tmp-buffer)) ind lst elt pos ret rel
  6529. (cperl-pod-here-fontify nil) f file)
  6530. (save-excursion
  6531. (if b (set-buffer b)
  6532. (cperl-setup-tmp-buf))
  6533. (erase-buffer)
  6534. (condition-case err
  6535. (setq file (car (insert-file-contents ifile)))
  6536. (error (if cperl-unreadable-ok nil
  6537. (if (y-or-n-p
  6538. (format "File %s unreadable. Continue? " ifile))
  6539. (setq cperl-unreadable-ok t)
  6540. (error "Aborting: unreadable file %s" ifile)))))
  6541. (if (not file)
  6542. (message "Unreadable file %s" ifile)
  6543. (message "Scanning file %s ..." file)
  6544. (if (and cperl-use-syntax-table-text-property-for-tags
  6545. (not xs))
  6546. (condition-case err ; after __END__ may have garbage
  6547. (cperl-find-pods-heres nil nil noninteractive)
  6548. (error (message "While scanning for syntax: %s" err))))
  6549. (if xs
  6550. (setq lst (cperl-xsub-scan))
  6551. (setq ind (cperl-imenu--create-perl-index))
  6552. (setq lst (cdr (assoc "+Unsorted List+..." ind))))
  6553. (setq lst
  6554. (mapcar
  6555. (function
  6556. (lambda (elt)
  6557. (cond ((string-match "^[_a-zA-Z]" (car elt))
  6558. (goto-char (cdr elt))
  6559. (beginning-of-line) ; pos should be of the start of the line
  6560. (list (car elt)
  6561. (point)
  6562. (1+ (count-lines 1 (point))) ; 1+ since at beg-o-l
  6563. (buffer-substring (progn
  6564. (goto-char (cdr elt))
  6565. ;; After name now...
  6566. (or (eolp) (forward-char 1))
  6567. (point))
  6568. (progn
  6569. (beginning-of-line)
  6570. (point))))))))
  6571. lst))
  6572. (erase-buffer)
  6573. (while lst
  6574. (setq elt (car lst) lst (cdr lst))
  6575. (if elt
  6576. (progn
  6577. (insert (elt elt 3)
  6578. 127
  6579. (if (string-match "^package " (car elt))
  6580. (substring (car elt) 8)
  6581. (car elt) )
  6582. 1
  6583. (number-to-string (elt elt 2)) ; Line
  6584. ","
  6585. (number-to-string (1- (elt elt 1))) ; Char pos 0-based
  6586. "\n")
  6587. (if (and (string-match "^[_a-zA-Z]+::" (car elt))
  6588. (string-match "^sub[ \t]+\\([_a-zA-Z]+\\)[^:_a-zA-Z]"
  6589. (elt elt 3)))
  6590. ;; Need to insert the name without package as well
  6591. (setq lst (cons (cons (substring (elt elt 3)
  6592. (match-beginning 1)
  6593. (match-end 1))
  6594. (cdr elt))
  6595. lst))))))
  6596. (setq pos (point))
  6597. (goto-char 1)
  6598. (setq rel file)
  6599. ;; On case-preserving filesystems (EMX on OS/2) case might be encoded in properties
  6600. (set-text-properties 0 (length rel) nil rel)
  6601. (and (equal topdir (substring rel 0 (length topdir)))
  6602. (setq rel (substring file (length topdir))))
  6603. (insert "\f\n" rel "," (number-to-string (1- pos)) "\n")
  6604. (setq ret (buffer-substring 1 (point-max)))
  6605. (erase-buffer)
  6606. (or noninteractive
  6607. (message "Scanning file %s finished" file))
  6608. ret))))
  6609. (defun cperl-add-tags-recurse-noxs ()
  6610. "Add to TAGS data for \"pure\" Perl files in the current directory and kids.
  6611. Use as
  6612. emacs -batch -q -no-site-file -l emacs/cperl-mode.el \
  6613. -f cperl-add-tags-recurse-noxs
  6614. "
  6615. (cperl-write-tags nil nil t t nil t))
  6616. (defun cperl-add-tags-recurse-noxs-fullpath ()
  6617. "Add to TAGS data for \"pure\" Perl in the current directory and kids.
  6618. Writes down fullpath, so TAGS is relocatable (but if the build directory
  6619. is relocated, the file TAGS inside it breaks). Use as
  6620. emacs -batch -q -no-site-file -l emacs/cperl-mode.el \
  6621. -f cperl-add-tags-recurse-noxs-fullpath
  6622. "
  6623. (cperl-write-tags nil nil t t nil t ""))
  6624. (defun cperl-add-tags-recurse ()
  6625. "Add to TAGS file data for Perl files in the current directory and kids.
  6626. Use as
  6627. emacs -batch -q -no-site-file -l emacs/cperl-mode.el \
  6628. -f cperl-add-tags-recurse
  6629. "
  6630. (cperl-write-tags nil nil t t))
  6631. (defun cperl-write-tags (&optional file erase recurse dir inbuffer noxs topdir)
  6632. ;; If INBUFFER, do not select buffer, and do not save
  6633. ;; If ERASE is `ignore', do not erase, and do not try to delete old info.
  6634. (require 'etags)
  6635. (if file nil
  6636. (setq file (if dir default-directory (buffer-file-name)))
  6637. (if (and (not dir) (buffer-modified-p)) (error "Save buffer first!")))
  6638. (or topdir
  6639. (setq topdir default-directory))
  6640. (let ((tags-file-name "TAGS")
  6641. (case-fold-search (and (featurep 'xemacs) (eq system-type 'emx)))
  6642. xs rel tm)
  6643. (save-excursion
  6644. (cond (inbuffer nil) ; Already there
  6645. ((file-exists-p tags-file-name)
  6646. (if (featurep 'xemacs)
  6647. (visit-tags-table-buffer)
  6648. (visit-tags-table-buffer tags-file-name)))
  6649. (t (set-buffer (find-file-noselect tags-file-name))))
  6650. (cond
  6651. (dir
  6652. (cond ((eq erase 'ignore))
  6653. (erase
  6654. (erase-buffer)
  6655. (setq erase 'ignore)))
  6656. (let ((files
  6657. (condition-case err
  6658. (directory-files file t
  6659. (if recurse nil cperl-scan-files-regexp)
  6660. t)
  6661. (error
  6662. (if cperl-unreadable-ok nil
  6663. (if (y-or-n-p
  6664. (format "Directory %s unreadable. Continue? " file))
  6665. (setq cperl-unreadable-ok t
  6666. tm nil) ; Return empty list
  6667. (error "Aborting: unreadable directory %s" file)))))))
  6668. (mapc (function
  6669. (lambda (file)
  6670. (cond
  6671. ((string-match cperl-noscan-files-regexp file)
  6672. nil)
  6673. ((not (file-directory-p file))
  6674. (if (string-match cperl-scan-files-regexp file)
  6675. (cperl-write-tags file erase recurse nil t noxs topdir)))
  6676. ((not recurse) nil)
  6677. (t (cperl-write-tags file erase recurse t t noxs topdir)))))
  6678. files)))
  6679. (t
  6680. (setq xs (string-match "\\.xs$" file))
  6681. (if (not (and xs noxs))
  6682. (progn
  6683. (cond ((eq erase 'ignore) (goto-char (point-max)))
  6684. (erase (erase-buffer))
  6685. (t
  6686. (goto-char 1)
  6687. (setq rel file)
  6688. ;; On case-preserving filesystems (EMX on OS/2) case might be encoded in properties
  6689. (set-text-properties 0 (length rel) nil rel)
  6690. (and (equal topdir (substring rel 0 (length topdir)))
  6691. (setq rel (substring file (length topdir))))
  6692. (if (search-forward (concat "\f\n" rel ",") nil t)
  6693. (progn
  6694. (search-backward "\f\n")
  6695. (delete-region (point)
  6696. (save-excursion
  6697. (forward-char 1)
  6698. (if (search-forward "\f\n"
  6699. nil 'toend)
  6700. (- (point) 2)
  6701. (point-max)))))
  6702. (goto-char (point-max)))))
  6703. (insert (cperl-find-tags file xs topdir))))))
  6704. (if inbuffer nil ; Delegate to the caller
  6705. (save-buffer 0) ; No backup
  6706. (if (fboundp 'initialize-new-tags-table) ; Do we need something special in XEmacs?
  6707. (initialize-new-tags-table))))))
  6708. (defvar cperl-tags-hier-regexp-list
  6709. (concat
  6710. "^\\("
  6711. "\\(package\\)\\>"
  6712. "\\|"
  6713. "sub\\>[^\n]+::"
  6714. "\\|"
  6715. "[a-zA-Z_][a-zA-Z_0-9:]*(\C-?[^\n]+::" ; XSUB?
  6716. "\\|"
  6717. "[ \t]*BOOT:\C-?[^\n]+::" ; BOOT section
  6718. "\\)"))
  6719. (defvar cperl-hierarchy '(() ())
  6720. "Global hierarchy of classes.")
  6721. (defun cperl-tags-hier-fill ()
  6722. ;; Suppose we are in a tag table cooked by cperl.
  6723. (goto-char 1)
  6724. (let (type pack name pos line chunk ord cons1 file str info fileind)
  6725. (while (re-search-forward cperl-tags-hier-regexp-list nil t)
  6726. (setq pos (match-beginning 0)
  6727. pack (match-beginning 2))
  6728. (beginning-of-line)
  6729. (if (looking-at (concat
  6730. "\\([^\n]+\\)"
  6731. "\C-?"
  6732. "\\([^\n]+\\)"
  6733. "\C-a"
  6734. "\\([0-9]+\\)"
  6735. ","
  6736. "\\([0-9]+\\)"))
  6737. (progn
  6738. (setq ;;str (buffer-substring (match-beginning 1) (match-end 1))
  6739. name (buffer-substring (match-beginning 2) (match-end 2))
  6740. ;;pos (buffer-substring (match-beginning 3) (match-end 3))
  6741. line (buffer-substring (match-beginning 3) (match-end 3))
  6742. ord (if pack 1 0)
  6743. file (file-of-tag)
  6744. fileind (format "%s:%s" file line)
  6745. ;; Moves to beginning of the next line:
  6746. info (cperl-etags-snarf-tag file line))
  6747. ;; Move back
  6748. (forward-char -1)
  6749. ;; Make new member of hierarchy name ==> file ==> pos if needed
  6750. (if (setq cons1 (assoc name (nth ord cperl-hierarchy)))
  6751. ;; Name known
  6752. (setcdr cons1 (cons (cons fileind (vector file info))
  6753. (cdr cons1)))
  6754. ;; First occurrence of the name, start alist
  6755. (setq cons1 (cons name (list (cons fileind (vector file info)))))
  6756. (if pack
  6757. (setcar (cdr cperl-hierarchy)
  6758. (cons cons1 (nth 1 cperl-hierarchy)))
  6759. (setcar cperl-hierarchy
  6760. (cons cons1 (car cperl-hierarchy)))))))
  6761. (end-of-line))))
  6762. (declare-function x-popup-menu "menu.c" (position menu))
  6763. (defun cperl-tags-hier-init (&optional update)
  6764. "Show hierarchical menu of classes and methods.
  6765. Finds info about classes by a scan of loaded TAGS files.
  6766. Supposes that the TAGS files contain fully qualified function names.
  6767. One may build such TAGS files from CPerl mode menu."
  6768. (interactive)
  6769. (require 'etags)
  6770. (require 'imenu)
  6771. (if (or update (null (nth 2 cperl-hierarchy)))
  6772. (let ((remover (function (lambda (elt) ; (name (file1...) (file2..))
  6773. (or (nthcdr 2 elt)
  6774. ;; Only in one file
  6775. (setcdr elt (cdr (nth 1 elt)))))))
  6776. pack name cons1 to l1 l2 l3 l4 b)
  6777. ;; (setq cperl-hierarchy '(() () ())) ; Would write into '() later!
  6778. (setq cperl-hierarchy (list l1 l2 l3))
  6779. (if (featurep 'xemacs) ; Not checked
  6780. (progn
  6781. (or tags-file-name
  6782. ;; Does this work in XEmacs?
  6783. (call-interactively 'visit-tags-table))
  6784. (message "Updating list of classes...")
  6785. (set-buffer (get-file-buffer tags-file-name))
  6786. (cperl-tags-hier-fill))
  6787. (or tags-table-list
  6788. (call-interactively 'visit-tags-table))
  6789. (mapc
  6790. (function
  6791. (lambda (tagsfile)
  6792. (message "Updating list of classes... %s" tagsfile)
  6793. (set-buffer (get-file-buffer tagsfile))
  6794. (cperl-tags-hier-fill)))
  6795. tags-table-list)
  6796. (message "Updating list of classes... postprocessing..."))
  6797. (mapc remover (car cperl-hierarchy))
  6798. (mapc remover (nth 1 cperl-hierarchy))
  6799. (setq to (list nil (cons "Packages: " (nth 1 cperl-hierarchy))
  6800. (cons "Methods: " (car cperl-hierarchy))))
  6801. (cperl-tags-treeify to 1)
  6802. (setcar (nthcdr 2 cperl-hierarchy)
  6803. (cperl-menu-to-keymap (cons '("+++UPDATE+++" . -999) (cdr to))))
  6804. (message "Updating list of classes: done, requesting display...")
  6805. ;;(cperl-imenu-addback (nth 2 cperl-hierarchy))
  6806. ))
  6807. (or (nth 2 cperl-hierarchy)
  6808. (error "No items found"))
  6809. (setq update
  6810. ;;; (imenu-choose-buffer-index "Packages: " (nth 2 cperl-hierarchy))
  6811. (if (if (fboundp 'display-popup-menus-p)
  6812. (let ((f 'display-popup-menus-p))
  6813. (funcall f))
  6814. window-system)
  6815. (x-popup-menu t (nth 2 cperl-hierarchy))
  6816. (require 'tmm)
  6817. (tmm-prompt (nth 2 cperl-hierarchy))))
  6818. (if (and update (listp update))
  6819. (progn (while (cdr update) (setq update (cdr update)))
  6820. (setq update (car update)))) ; Get the last from the list
  6821. (if (vectorp update)
  6822. (progn
  6823. (find-file (elt update 0))
  6824. (cperl-etags-goto-tag-location (elt update 1))))
  6825. (if (eq update -999) (cperl-tags-hier-init t)))
  6826. (defun cperl-tags-treeify (to level)
  6827. ;; cadr of `to' is read-write. On start it is a cons
  6828. (let* ((regexp (concat "^\\(" (mapconcat
  6829. 'identity
  6830. (make-list level "[_a-zA-Z0-9]+")
  6831. "::")
  6832. "\\)\\(::\\)?"))
  6833. (packages (cdr (nth 1 to)))
  6834. (methods (cdr (nth 2 to)))
  6835. l1 head tail cons1 cons2 ord writeto packs recurse
  6836. root-packages root-functions ms many_ms same_name ps
  6837. (move-deeper
  6838. (function
  6839. (lambda (elt)
  6840. (cond ((and (string-match regexp (car elt))
  6841. (or (eq ord 1) (match-end 2)))
  6842. (setq head (substring (car elt) 0 (match-end 1))
  6843. tail (if (match-end 2) (substring (car elt)
  6844. (match-end 2)))
  6845. recurse t)
  6846. (if (setq cons1 (assoc head writeto)) nil
  6847. ;; Need to init new head
  6848. (setcdr writeto (cons (list head (list "Packages: ")
  6849. (list "Methods: "))
  6850. (cdr writeto)))
  6851. (setq cons1 (nth 1 writeto)))
  6852. (setq cons2 (nth ord cons1)) ; Either packs or meths
  6853. (setcdr cons2 (cons elt (cdr cons2))))
  6854. ((eq ord 2)
  6855. (setq root-functions (cons elt root-functions)))
  6856. (t
  6857. (setq root-packages (cons elt root-packages))))))))
  6858. (setcdr to l1) ; Init to dynamic space
  6859. (setq writeto to)
  6860. (setq ord 1)
  6861. (mapc move-deeper packages)
  6862. (setq ord 2)
  6863. (mapc move-deeper methods)
  6864. (if recurse
  6865. (mapc (function (lambda (elt)
  6866. (cperl-tags-treeify elt (1+ level))))
  6867. (cdr to)))
  6868. ;;Now clean up leaders with one child only
  6869. (mapc (function (lambda (elt)
  6870. (if (not (and (listp (cdr elt))
  6871. (eq (length elt) 2))) nil
  6872. (setcar elt (car (nth 1 elt)))
  6873. (setcdr elt (cdr (nth 1 elt))))))
  6874. (cdr to))
  6875. ;; Sort the roots of subtrees
  6876. (if (default-value 'imenu-sort-function)
  6877. (setcdr to
  6878. (sort (cdr to) (default-value 'imenu-sort-function))))
  6879. ;; Now add back functions removed from display
  6880. (mapc (function (lambda (elt)
  6881. (setcdr to (cons elt (cdr to)))))
  6882. (if (default-value 'imenu-sort-function)
  6883. (nreverse
  6884. (sort root-functions (default-value 'imenu-sort-function)))
  6885. root-functions))
  6886. ;; Now add back packages removed from display
  6887. (mapc (function (lambda (elt)
  6888. (setcdr to (cons (cons (concat "package " (car elt))
  6889. (cdr elt))
  6890. (cdr to)))))
  6891. (if (default-value 'imenu-sort-function)
  6892. (nreverse
  6893. (sort root-packages (default-value 'imenu-sort-function)))
  6894. root-packages))))
  6895. ;;;(x-popup-menu t
  6896. ;;; '(keymap "Name1"
  6897. ;;; ("Ret1" "aa")
  6898. ;;; ("Head1" "ab"
  6899. ;;; keymap "Name2"
  6900. ;;; ("Tail1" "x") ("Tail2" "y"))))
  6901. (defun cperl-list-fold (list name limit)
  6902. (let (list1 list2 elt1 (num 0))
  6903. (if (<= (length list) limit) list
  6904. (setq list1 nil list2 nil)
  6905. (while list
  6906. (setq num (1+ num)
  6907. elt1 (car list)
  6908. list (cdr list))
  6909. (if (<= num imenu-max-items)
  6910. (setq list2 (cons elt1 list2))
  6911. (setq list1 (cons (cons name
  6912. (nreverse list2))
  6913. list1)
  6914. list2 (list elt1)
  6915. num 1)))
  6916. (nreverse (cons (cons name
  6917. (nreverse list2))
  6918. list1)))))
  6919. (defun cperl-menu-to-keymap (menu &optional name)
  6920. (let (list)
  6921. (cons 'keymap
  6922. (mapcar
  6923. (function
  6924. (lambda (elt)
  6925. (cond ((listp (cdr elt))
  6926. (setq list (cperl-list-fold
  6927. (cdr elt) (car elt) imenu-max-items))
  6928. (cons nil
  6929. (cons (car elt)
  6930. (cperl-menu-to-keymap list))))
  6931. (t
  6932. (list (cdr elt) (car elt) t))))) ; t is needed in 19.34
  6933. (cperl-list-fold menu "Root" imenu-max-items)))))
  6934. (defvar cperl-bad-style-regexp
  6935. (mapconcat 'identity
  6936. '("[^-\n\t <>=+!.&|(*/'`\"#^][-=+<>!|&^]" ; char sign
  6937. "[-<>=+^&|]+[^- \t\n=+<>~]") ; sign+ char
  6938. "\\|")
  6939. "Finds places such that insertion of a whitespace may help a lot.")
  6940. (defvar cperl-not-bad-style-regexp
  6941. (mapconcat
  6942. 'identity
  6943. '("[^-\t <>=+]\\(--\\|\\+\\+\\)" ; var-- var++
  6944. "[a-zA-Z0-9_][|&][a-zA-Z0-9_$]" ; abc|def abc&def are often used.
  6945. "&[(a-zA-Z0-9_$]" ; &subroutine &(var->field)
  6946. "<\\$?\\sw+\\(\\.\\(\\sw\\|_\\)+\\)?>" ; <IN> <stdin.h>
  6947. "-[a-zA-Z][ \t]+[_$\"'`a-zA-Z]" ; -f file, -t STDIN
  6948. "-[0-9]" ; -5
  6949. "\\+\\+" ; ++var
  6950. "--" ; --var
  6951. ".->" ; a->b
  6952. "->" ; a SPACE ->b
  6953. "\\[-" ; a[-1]
  6954. "\\\\[&$@*\\\\]" ; \&func
  6955. "^=" ; =head
  6956. "\\$." ; $|
  6957. "<<[a-zA-Z_'\"`]" ; <<FOO, <<'FOO'
  6958. "||"
  6959. "&&"
  6960. "[CBIXSLFZ]<\\(\\sw\\|\\s \\|\\s_\\|[\n]\\)*>" ; C<code like text>
  6961. "-[a-zA-Z_0-9]+[ \t]*=>" ; -option => value
  6962. ;; Unaddressed trouble spots: = -abc, f(56, -abc) --- specialcased below
  6963. ;;"[*/+-|&<.]+="
  6964. )
  6965. "\\|")
  6966. "If matches at the start of match found by `my-bad-c-style-regexp',
  6967. insertion of a whitespace will not help.")
  6968. (defvar found-bad)
  6969. (defun cperl-find-bad-style ()
  6970. "Find places in the buffer where insertion of a whitespace may help.
  6971. Prompts user for insertion of spaces.
  6972. Currently it is tuned to C and Perl syntax."
  6973. (interactive)
  6974. (let (found-bad (p (point)))
  6975. (setq last-nonmenu-event 13) ; To disable popup
  6976. (goto-char (point-min))
  6977. (map-y-or-n-p "Insert space here? "
  6978. (lambda (arg) (insert " "))
  6979. 'cperl-next-bad-style
  6980. '("location" "locations" "insert a space into")
  6981. '((?\C-r (lambda (arg)
  6982. (let ((buffer-quit-function
  6983. 'exit-recursive-edit))
  6984. (message "Exit with Esc Esc")
  6985. (recursive-edit)
  6986. t)) ; Consider acted upon
  6987. "edit, exit with Esc Esc")
  6988. (?e (lambda (arg)
  6989. (let ((buffer-quit-function
  6990. 'exit-recursive-edit))
  6991. (message "Exit with Esc Esc")
  6992. (recursive-edit)
  6993. t)) ; Consider acted upon
  6994. "edit, exit with Esc Esc"))
  6995. t)
  6996. (if found-bad (goto-char found-bad)
  6997. (goto-char p)
  6998. (message "No appropriate place found"))))
  6999. (defun cperl-next-bad-style ()
  7000. (let (p (not-found t) (point (point)) found)
  7001. (while (and not-found
  7002. (re-search-forward cperl-bad-style-regexp nil 'to-end))
  7003. (setq p (point))
  7004. (goto-char (match-beginning 0))
  7005. (if (or
  7006. (looking-at cperl-not-bad-style-regexp)
  7007. ;; Check for a < -b and friends
  7008. (and (eq (following-char) ?\-)
  7009. (save-excursion
  7010. (skip-chars-backward " \t\n")
  7011. (memq (preceding-char) '(?\= ?\> ?\< ?\, ?\( ?\[ ?\{))))
  7012. ;; Now check for syntax type
  7013. (save-match-data
  7014. (setq found (point))
  7015. (beginning-of-defun)
  7016. (let ((pps (parse-partial-sexp (point) found)))
  7017. (or (nth 3 pps) (nth 4 pps) (nth 5 pps)))))
  7018. (goto-char (match-end 0))
  7019. (goto-char (1- p))
  7020. (setq not-found nil
  7021. found-bad found)))
  7022. (not not-found)))
  7023. ;;; Getting help
  7024. (defvar cperl-have-help-regexp
  7025. ;;(concat "\\("
  7026. (mapconcat
  7027. 'identity
  7028. '("[$@%*&][0-9a-zA-Z_:]+\\([ \t]*[[{]\\)?" ; Usual variable
  7029. "[$@]\\^[a-zA-Z]" ; Special variable
  7030. "[$@][^ \n\t]" ; Special variable
  7031. "-[a-zA-Z]" ; File test
  7032. "\\\\[a-zA-Z0]" ; Special chars
  7033. "^=[a-z][a-zA-Z0-9_]*" ; POD sections
  7034. "[-!&*+,-./<=>?\\\\^|~]+" ; Operator
  7035. "[a-zA-Z_0-9:]+" ; symbol or number
  7036. "x="
  7037. "#!")
  7038. ;;"\\)\\|\\("
  7039. "\\|")
  7040. ;;"\\)"
  7041. ;;)
  7042. "Matches places in the buffer we can find help for.")
  7043. (defvar cperl-message-on-help-error t)
  7044. (defvar cperl-help-from-timer nil)
  7045. (defun cperl-word-at-point-hard ()
  7046. ;; Does not save-excursion
  7047. ;; Get to the something meaningful
  7048. (or (eobp) (eolp) (forward-char 1))
  7049. (re-search-backward "[-a-zA-Z0-9_:!&*+,-./<=>?\\\\^|~$%@]"
  7050. (point-at-bol)
  7051. 'to-beg)
  7052. ;; (cond
  7053. ;; ((or (eobp) (looking-at "[][ \t\n{}();,]")) ; Not at a symbol
  7054. ;; (skip-chars-backward " \n\t\r({[]});,")
  7055. ;; (or (bobp) (backward-char 1))))
  7056. ;; Try to backtrace
  7057. (cond
  7058. ((looking-at "[a-zA-Z0-9_:]") ; symbol
  7059. (skip-chars-backward "a-zA-Z0-9_:")
  7060. (cond
  7061. ((and (eq (preceding-char) ?^) ; $^I
  7062. (eq (char-after (- (point) 2)) ?\$))
  7063. (forward-char -2))
  7064. ((memq (preceding-char) (append "*$@%&\\" nil)) ; *glob
  7065. (forward-char -1))
  7066. ((and (eq (preceding-char) ?\=)
  7067. (eq (current-column) 1))
  7068. (forward-char -1))) ; =head1
  7069. (if (and (eq (preceding-char) ?\<)
  7070. (looking-at "\\$?[a-zA-Z0-9_:]+>")) ; <FH>
  7071. (forward-char -1)))
  7072. ((and (looking-at "=") (eq (preceding-char) ?x)) ; x=
  7073. (forward-char -1))
  7074. ((and (looking-at "\\^") (eq (preceding-char) ?\$)) ; $^I
  7075. (forward-char -1))
  7076. ((looking-at "[-!&*+,-./<=>?\\\\^|~]")
  7077. (skip-chars-backward "-!&*+,-./<=>?\\\\^|~")
  7078. (cond
  7079. ((and (eq (preceding-char) ?\$)
  7080. (not (eq (char-after (- (point) 2)) ?\$))) ; $-
  7081. (forward-char -1))
  7082. ((and (eq (following-char) ?\>)
  7083. (string-match "[a-zA-Z0-9_]" (char-to-string (preceding-char)))
  7084. (save-excursion
  7085. (forward-sexp -1)
  7086. (and (eq (preceding-char) ?\<)
  7087. (looking-at "\\$?[a-zA-Z0-9_:]+>")))) ; <FH>
  7088. (search-backward "<"))))
  7089. ((and (eq (following-char) ?\$)
  7090. (eq (preceding-char) ?\<)
  7091. (looking-at "\\$?[a-zA-Z0-9_:]+>")) ; <$fh>
  7092. (forward-char -1)))
  7093. (if (looking-at cperl-have-help-regexp)
  7094. (buffer-substring (match-beginning 0) (match-end 0))))
  7095. (defun cperl-get-help ()
  7096. "Get one-line docs on the symbol at the point.
  7097. The data for these docs is a little bit obsolete and may be in fact longer
  7098. than a line. Your contribution to update/shorten it is appreciated."
  7099. (interactive)
  7100. (save-match-data ; May be called "inside" query-replace
  7101. (save-excursion
  7102. (let ((word (cperl-word-at-point-hard)))
  7103. (if word
  7104. (if (and cperl-help-from-timer ; Bail out if not in mainland
  7105. (not (string-match "^#!\\|\\\\\\|^=" word)) ; Show help even in comments/strings.
  7106. (or (memq (get-text-property (point) 'face)
  7107. '(font-lock-comment-face font-lock-string-face))
  7108. (memq (get-text-property (point) 'syntax-type)
  7109. '(pod here-doc format))))
  7110. nil
  7111. (cperl-describe-perl-symbol word))
  7112. (if cperl-message-on-help-error
  7113. (message "Nothing found for %s..."
  7114. (buffer-substring (point) (min (+ 5 (point)) (point-max))))))))))
  7115. ;;; Stolen from perl-descr.el by Johan Vromans:
  7116. (defvar cperl-doc-buffer " *perl-doc*"
  7117. "Where the documentation can be found.")
  7118. (defun cperl-describe-perl-symbol (val)
  7119. "Display the documentation of symbol at point, a Perl operator."
  7120. (let ((enable-recursive-minibuffers t)
  7121. args-file regexp)
  7122. (cond
  7123. ((string-match "^[&*][a-zA-Z_]" val)
  7124. (setq val (concat (substring val 0 1) "NAME")))
  7125. ((string-match "^[$@]\\([a-zA-Z_:0-9]+\\)[ \t]*\\[" val)
  7126. (setq val (concat "@" (substring val 1 (match-end 1)))))
  7127. ((string-match "^[$@]\\([a-zA-Z_:0-9]+\\)[ \t]*{" val)
  7128. (setq val (concat "%" (substring val 1 (match-end 1)))))
  7129. ((and (string= val "x") (string-match "^x=" val))
  7130. (setq val "x="))
  7131. ((string-match "^\\$[\C-a-\C-z]" val)
  7132. (setq val (concat "$^" (char-to-string (+ ?A -1 (aref val 1))))))
  7133. ((string-match "^CORE::" val)
  7134. (setq val "CORE::"))
  7135. ((string-match "^SUPER::" val)
  7136. (setq val "SUPER::"))
  7137. ((and (string= "<" val) (string-match "^<\\$?[a-zA-Z0-9_:]+>" val))
  7138. (setq val "<NAME>")))
  7139. (setq regexp (concat "^"
  7140. "\\([^a-zA-Z0-9_:]+[ \t]+\\)?"
  7141. (regexp-quote val)
  7142. "\\([ \t([/]\\|$\\)"))
  7143. ;; get the buffer with the documentation text
  7144. (cperl-switch-to-doc-buffer)
  7145. ;; lookup in the doc
  7146. (goto-char (point-min))
  7147. (let ((case-fold-search nil))
  7148. (list
  7149. (if (re-search-forward regexp (point-max) t)
  7150. (save-excursion
  7151. (beginning-of-line 1)
  7152. (let ((lnstart (point)))
  7153. (end-of-line)
  7154. (message "%s" (buffer-substring lnstart (point)))))
  7155. (if cperl-message-on-help-error
  7156. (message "No definition for %s" val)))))))
  7157. (defvar cperl-short-docs 'please-ignore-this-line
  7158. ;; Perl4 version was written by Johan Vromans (jvromans@squirrel.nl)
  7159. "# based on '@(#)@ perl-descr.el 1.9 - describe-perl-symbol' [Perl 5]
  7160. ... Range (list context); flip/flop [no flop when flip] (scalar context).
  7161. ! ... Logical negation.
  7162. ... != ... Numeric inequality.
  7163. ... !~ ... Search pattern, substitution, or translation (negated).
  7164. $! In numeric context: errno. In a string context: error string.
  7165. $\" The separator which joins elements of arrays interpolated in strings.
  7166. $# The output format for printed numbers. Default is %.15g or close.
  7167. $$ Process number of this script. Changes in the fork()ed child process.
  7168. $% The current page number of the currently selected output channel.
  7169. The following variables are always local to the current block:
  7170. $1 Match of the 1st set of parentheses in the last match (auto-local).
  7171. $2 Match of the 2nd set of parentheses in the last match (auto-local).
  7172. $3 Match of the 3rd set of parentheses in the last match (auto-local).
  7173. $4 Match of the 4th set of parentheses in the last match (auto-local).
  7174. $5 Match of the 5th set of parentheses in the last match (auto-local).
  7175. $6 Match of the 6th set of parentheses in the last match (auto-local).
  7176. $7 Match of the 7th set of parentheses in the last match (auto-local).
  7177. $8 Match of the 8th set of parentheses in the last match (auto-local).
  7178. $9 Match of the 9th set of parentheses in the last match (auto-local).
  7179. $& The string matched by the last pattern match (auto-local).
  7180. $' The string after what was matched by the last match (auto-local).
  7181. $` The string before what was matched by the last match (auto-local).
  7182. $( The real gid of this process.
  7183. $) The effective gid of this process.
  7184. $* Deprecated: Set to 1 to do multiline matching within a string.
  7185. $+ The last bracket matched by the last search pattern.
  7186. $, The output field separator for the print operator.
  7187. $- The number of lines left on the page.
  7188. $. The current input line number of the last filehandle that was read.
  7189. $/ The input record separator, newline by default.
  7190. $0 Name of the file containing the current perl script (read/write).
  7191. $: String may be broken after these characters to fill ^-lines in a format.
  7192. $; Subscript separator for multi-dim array emulation. Default \"\\034\".
  7193. $< The real uid of this process.
  7194. $= The page length of the current output channel. Default is 60 lines.
  7195. $> The effective uid of this process.
  7196. $? The status returned by the last ``, pipe close or `system'.
  7197. $@ The perl error message from the last eval or do @var{EXPR} command.
  7198. $ARGV The name of the current file used with <> .
  7199. $[ Deprecated: The index of the first element/char in an array/string.
  7200. $\\ The output record separator for the print operator.
  7201. $] The perl version string as displayed with perl -v.
  7202. $^ The name of the current top-of-page format.
  7203. $^A The current value of the write() accumulator for format() lines.
  7204. $^D The value of the perl debug (-D) flags.
  7205. $^E Information about the last system error other than that provided by $!.
  7206. $^F The highest system file descriptor, ordinarily 2.
  7207. $^H The current set of syntax checks enabled by `use strict'.
  7208. $^I The value of the in-place edit extension (perl -i option).
  7209. $^L What formats output to perform a formfeed. Default is \\f.
  7210. $^M A buffer for emergency memory allocation when running out of memory.
  7211. $^O The operating system name under which this copy of Perl was built.
  7212. $^P Internal debugging flag.
  7213. $^T The time the script was started. Used by -A/-M/-C file tests.
  7214. $^W True if warnings are requested (perl -w flag).
  7215. $^X The name under which perl was invoked (argv[0] in C-speech).
  7216. $_ The default input and pattern-searching space.
  7217. $| Auto-flush after write/print on current output channel? Default 0.
  7218. $~ The name of the current report format.
  7219. ... % ... Modulo division.
  7220. ... %= ... Modulo division assignment.
  7221. %ENV Contains the current environment.
  7222. %INC List of files that have been require-d or do-ne.
  7223. %SIG Used to set signal handlers for various signals.
  7224. ... & ... Bitwise and.
  7225. ... && ... Logical and.
  7226. ... &&= ... Logical and assignment.
  7227. ... &= ... Bitwise and assignment.
  7228. ... * ... Multiplication.
  7229. ... ** ... Exponentiation.
  7230. *NAME Glob: all objects referred by NAME. *NAM1 = *NAM2 aliases NAM1 to NAM2.
  7231. &NAME(arg0, ...) Subroutine call. Arguments go to @_.
  7232. ... + ... Addition. +EXPR Makes EXPR into scalar context.
  7233. ++ Auto-increment (magical on strings). ++EXPR EXPR++
  7234. ... += ... Addition assignment.
  7235. , Comma operator.
  7236. ... - ... Subtraction.
  7237. -- Auto-decrement (NOT magical on strings). --EXPR EXPR--
  7238. ... -= ... Subtraction assignment.
  7239. -A Access time in days since script started.
  7240. -B File is a non-text (binary) file.
  7241. -C Inode change time in days since script started.
  7242. -M Age in days since script started.
  7243. -O File is owned by real uid.
  7244. -R File is readable by real uid.
  7245. -S File is a socket .
  7246. -T File is a text file.
  7247. -W File is writable by real uid.
  7248. -X File is executable by real uid.
  7249. -b File is a block special file.
  7250. -c File is a character special file.
  7251. -d File is a directory.
  7252. -e File exists .
  7253. -f File is a plain file.
  7254. -g File has setgid bit set.
  7255. -k File has sticky bit set.
  7256. -l File is a symbolic link.
  7257. -o File is owned by effective uid.
  7258. -p File is a named pipe (FIFO).
  7259. -r File is readable by effective uid.
  7260. -s File has non-zero size.
  7261. -t Tests if filehandle (STDIN by default) is opened to a tty.
  7262. -u File has setuid bit set.
  7263. -w File is writable by effective uid.
  7264. -x File is executable by effective uid.
  7265. -z File has zero size.
  7266. . Concatenate strings.
  7267. .. Range (list context); flip/flop (scalar context) operator.
  7268. .= Concatenate assignment strings
  7269. ... / ... Division. /PATTERN/ioxsmg Pattern match
  7270. ... /= ... Division assignment.
  7271. /PATTERN/ioxsmg Pattern match.
  7272. ... < ... Numeric less than. <pattern> Glob. See <NAME>, <> as well.
  7273. <NAME> Reads line from filehandle NAME (a bareword or dollar-bareword).
  7274. <pattern> Glob (Unless pattern is bareword/dollar-bareword - see <NAME>).
  7275. <> Reads line from union of files in @ARGV (= command line) and STDIN.
  7276. ... << ... Bitwise shift left. << start of HERE-DOCUMENT.
  7277. ... <= ... Numeric less than or equal to.
  7278. ... <=> ... Numeric compare.
  7279. ... = ... Assignment.
  7280. ... == ... Numeric equality.
  7281. ... =~ ... Search pattern, substitution, or translation
  7282. ... > ... Numeric greater than.
  7283. ... >= ... Numeric greater than or equal to.
  7284. ... >> ... Bitwise shift right.
  7285. ... >>= ... Bitwise shift right assignment.
  7286. ... ? ... : ... Condition=if-then-else operator. ?PAT? One-time pattern match.
  7287. ?PATTERN? One-time pattern match.
  7288. @ARGV Command line arguments (not including the command name - see $0).
  7289. @INC List of places to look for perl scripts during do/include/use.
  7290. @_ Parameter array for subroutines; result of split() unless in list context.
  7291. \\ Creates reference to what follows, like \\$var, or quotes non-\\w in strings.
  7292. \\0 Octal char, e.g. \\033.
  7293. \\E Case modification terminator. See \\Q, \\L, and \\U.
  7294. \\L Lowercase until \\E . See also \\l, lc.
  7295. \\U Upcase until \\E . See also \\u, uc.
  7296. \\Q Quote metacharacters until \\E . See also quotemeta.
  7297. \\a Alarm character (octal 007).
  7298. \\b Backspace character (octal 010).
  7299. \\c Control character, e.g. \\c[ .
  7300. \\e Escape character (octal 033).
  7301. \\f Formfeed character (octal 014).
  7302. \\l Lowercase the next character. See also \\L and \\u, lcfirst.
  7303. \\n Newline character (octal 012 on most systems).
  7304. \\r Return character (octal 015 on most systems).
  7305. \\t Tab character (octal 011).
  7306. \\u Upcase the next character. See also \\U and \\l, ucfirst.
  7307. \\x Hex character, e.g. \\x1b.
  7308. ... ^ ... Bitwise exclusive or.
  7309. __END__ Ends program source.
  7310. __DATA__ Ends program source.
  7311. __FILE__ Current (source) filename.
  7312. __LINE__ Current line in current source.
  7313. __PACKAGE__ Current package.
  7314. ARGV Default multi-file input filehandle. <ARGV> is a synonym for <>.
  7315. ARGVOUT Output filehandle with -i flag.
  7316. BEGIN { ... } Immediately executed (during compilation) piece of code.
  7317. END { ... } Pseudo-subroutine executed after the script finishes.
  7318. CHECK { ... } Pseudo-subroutine executed after the script is compiled.
  7319. INIT { ... } Pseudo-subroutine executed before the script starts running.
  7320. DATA Input filehandle for what follows after __END__ or __DATA__.
  7321. accept(NEWSOCKET,GENERICSOCKET)
  7322. alarm(SECONDS)
  7323. atan2(X,Y)
  7324. bind(SOCKET,NAME)
  7325. binmode(FILEHANDLE)
  7326. caller[(LEVEL)]
  7327. chdir(EXPR)
  7328. chmod(LIST)
  7329. chop[(LIST|VAR)]
  7330. chown(LIST)
  7331. chroot(FILENAME)
  7332. close(FILEHANDLE)
  7333. closedir(DIRHANDLE)
  7334. ... cmp ... String compare.
  7335. connect(SOCKET,NAME)
  7336. continue of { block } continue { block }. Is executed after `next' or at end.
  7337. cos(EXPR)
  7338. crypt(PLAINTEXT,SALT)
  7339. dbmclose(%HASH)
  7340. dbmopen(%HASH,DBNAME,MODE)
  7341. defined(EXPR)
  7342. delete($HASH{KEY})
  7343. die(LIST)
  7344. do { ... }|SUBR while|until EXPR executes at least once
  7345. do(EXPR|SUBR([LIST])) (with while|until executes at least once)
  7346. dump LABEL
  7347. each(%HASH)
  7348. endgrent
  7349. endhostent
  7350. endnetent
  7351. endprotoent
  7352. endpwent
  7353. endservent
  7354. eof[([FILEHANDLE])]
  7355. ... eq ... String equality.
  7356. eval(EXPR) or eval { BLOCK }
  7357. exec([TRUENAME] ARGV0, ARGVs) or exec(SHELL_COMMAND_LINE)
  7358. exit(EXPR)
  7359. exp(EXPR)
  7360. fcntl(FILEHANDLE,FUNCTION,SCALAR)
  7361. fileno(FILEHANDLE)
  7362. flock(FILEHANDLE,OPERATION)
  7363. for (EXPR;EXPR;EXPR) { ... }
  7364. foreach [VAR] (@ARRAY) { ... }
  7365. fork
  7366. ... ge ... String greater than or equal.
  7367. getc[(FILEHANDLE)]
  7368. getgrent
  7369. getgrgid(GID)
  7370. getgrnam(NAME)
  7371. gethostbyaddr(ADDR,ADDRTYPE)
  7372. gethostbyname(NAME)
  7373. gethostent
  7374. getlogin
  7375. getnetbyaddr(ADDR,ADDRTYPE)
  7376. getnetbyname(NAME)
  7377. getnetent
  7378. getpeername(SOCKET)
  7379. getpgrp(PID)
  7380. getppid
  7381. getpriority(WHICH,WHO)
  7382. getprotobyname(NAME)
  7383. getprotobynumber(NUMBER)
  7384. getprotoent
  7385. getpwent
  7386. getpwnam(NAME)
  7387. getpwuid(UID)
  7388. getservbyname(NAME,PROTO)
  7389. getservbyport(PORT,PROTO)
  7390. getservent
  7391. getsockname(SOCKET)
  7392. getsockopt(SOCKET,LEVEL,OPTNAME)
  7393. gmtime(EXPR)
  7394. goto LABEL
  7395. ... gt ... String greater than.
  7396. hex(EXPR)
  7397. if (EXPR) { ... } [ elsif (EXPR) { ... } ... ] [ else { ... } ] or EXPR if EXPR
  7398. index(STR,SUBSTR[,OFFSET])
  7399. int(EXPR)
  7400. ioctl(FILEHANDLE,FUNCTION,SCALAR)
  7401. join(EXPR,LIST)
  7402. keys(%HASH)
  7403. kill(LIST)
  7404. last [LABEL]
  7405. ... le ... String less than or equal.
  7406. length(EXPR)
  7407. link(OLDFILE,NEWFILE)
  7408. listen(SOCKET,QUEUESIZE)
  7409. local(LIST)
  7410. localtime(EXPR)
  7411. log(EXPR)
  7412. lstat(EXPR|FILEHANDLE|VAR)
  7413. ... lt ... String less than.
  7414. m/PATTERN/iogsmx
  7415. mkdir(FILENAME,MODE)
  7416. msgctl(ID,CMD,ARG)
  7417. msgget(KEY,FLAGS)
  7418. msgrcv(ID,VAR,SIZE,TYPE.FLAGS)
  7419. msgsnd(ID,MSG,FLAGS)
  7420. my VAR or my (VAR1,...) Introduces a lexical variable ($VAR, @ARR, or %HASH).
  7421. our VAR or our (VAR1,...) Lexically enable a global variable ($V, @A, or %H).
  7422. ... ne ... String inequality.
  7423. next [LABEL]
  7424. oct(EXPR)
  7425. open(FILEHANDLE[,EXPR])
  7426. opendir(DIRHANDLE,EXPR)
  7427. ord(EXPR) ASCII value of the first char of the string.
  7428. pack(TEMPLATE,LIST)
  7429. package NAME Introduces package context.
  7430. pipe(READHANDLE,WRITEHANDLE) Create a pair of filehandles on ends of a pipe.
  7431. pop(ARRAY)
  7432. print [FILEHANDLE] [(LIST)]
  7433. printf [FILEHANDLE] (FORMAT,LIST)
  7434. push(ARRAY,LIST)
  7435. q/STRING/ Synonym for 'STRING'
  7436. qq/STRING/ Synonym for \"STRING\"
  7437. qx/STRING/ Synonym for `STRING`
  7438. rand[(EXPR)]
  7439. read(FILEHANDLE,SCALAR,LENGTH[,OFFSET])
  7440. readdir(DIRHANDLE)
  7441. readlink(EXPR)
  7442. recv(SOCKET,SCALAR,LEN,FLAGS)
  7443. redo [LABEL]
  7444. rename(OLDNAME,NEWNAME)
  7445. require [FILENAME | PERL_VERSION]
  7446. reset[(EXPR)]
  7447. return(LIST)
  7448. reverse(LIST)
  7449. rewinddir(DIRHANDLE)
  7450. rindex(STR,SUBSTR[,OFFSET])
  7451. rmdir(FILENAME)
  7452. s/PATTERN/REPLACEMENT/gieoxsm
  7453. scalar(EXPR)
  7454. seek(FILEHANDLE,POSITION,WHENCE)
  7455. seekdir(DIRHANDLE,POS)
  7456. select(FILEHANDLE | RBITS,WBITS,EBITS,TIMEOUT)
  7457. semctl(ID,SEMNUM,CMD,ARG)
  7458. semget(KEY,NSEMS,SIZE,FLAGS)
  7459. semop(KEY,...)
  7460. send(SOCKET,MSG,FLAGS[,TO])
  7461. setgrent
  7462. sethostent(STAYOPEN)
  7463. setnetent(STAYOPEN)
  7464. setpgrp(PID,PGRP)
  7465. setpriority(WHICH,WHO,PRIORITY)
  7466. setprotoent(STAYOPEN)
  7467. setpwent
  7468. setservent(STAYOPEN)
  7469. setsockopt(SOCKET,LEVEL,OPTNAME,OPTVAL)
  7470. shift[(ARRAY)]
  7471. shmctl(ID,CMD,ARG)
  7472. shmget(KEY,SIZE,FLAGS)
  7473. shmread(ID,VAR,POS,SIZE)
  7474. shmwrite(ID,STRING,POS,SIZE)
  7475. shutdown(SOCKET,HOW)
  7476. sin(EXPR)
  7477. sleep[(EXPR)]
  7478. socket(SOCKET,DOMAIN,TYPE,PROTOCOL)
  7479. socketpair(SOCKET1,SOCKET2,DOMAIN,TYPE,PROTOCOL)
  7480. sort [SUBROUTINE] (LIST)
  7481. splice(ARRAY,OFFSET[,LENGTH[,LIST]])
  7482. split[(/PATTERN/[,EXPR[,LIMIT]])]
  7483. sprintf(FORMAT,LIST)
  7484. sqrt(EXPR)
  7485. srand(EXPR)
  7486. stat(EXPR|FILEHANDLE|VAR)
  7487. study[(SCALAR)]
  7488. sub [NAME [(format)]] { BODY } sub NAME [(format)]; sub [(format)] {...}
  7489. substr(EXPR,OFFSET[,LEN])
  7490. symlink(OLDFILE,NEWFILE)
  7491. syscall(LIST)
  7492. sysread(FILEHANDLE,SCALAR,LENGTH[,OFFSET])
  7493. system([TRUENAME] ARGV0 [,ARGV]) or system(SHELL_COMMAND_LINE)
  7494. syswrite(FILEHANDLE,SCALAR,LENGTH[,OFFSET])
  7495. tell[(FILEHANDLE)]
  7496. telldir(DIRHANDLE)
  7497. time
  7498. times
  7499. tr/SEARCHLIST/REPLACEMENTLIST/cds
  7500. truncate(FILE|EXPR,LENGTH)
  7501. umask[(EXPR)]
  7502. undef[(EXPR)]
  7503. unless (EXPR) { ... } [ else { ... } ] or EXPR unless EXPR
  7504. unlink(LIST)
  7505. unpack(TEMPLATE,EXPR)
  7506. unshift(ARRAY,LIST)
  7507. until (EXPR) { ... } EXPR until EXPR
  7508. utime(LIST)
  7509. values(%HASH)
  7510. vec(EXPR,OFFSET,BITS)
  7511. wait
  7512. waitpid(PID,FLAGS)
  7513. wantarray Returns true if the sub/eval is called in list context.
  7514. warn(LIST)
  7515. while (EXPR) { ... } EXPR while EXPR
  7516. write[(EXPR|FILEHANDLE)]
  7517. ... x ... Repeat string or array.
  7518. x= ... Repetition assignment.
  7519. y/SEARCHLIST/REPLACEMENTLIST/
  7520. ... | ... Bitwise or.
  7521. ... || ... Logical or.
  7522. ~ ... Unary bitwise complement.
  7523. #! OS interpreter indicator. If contains `perl', used for options, and -x.
  7524. AUTOLOAD {...} Shorthand for `sub AUTOLOAD {...}'.
  7525. CORE:: Prefix to access builtin function if imported sub obscures it.
  7526. SUPER:: Prefix to lookup for a method in @ISA classes.
  7527. DESTROY Shorthand for `sub DESTROY {...}'.
  7528. ... EQ ... Obsolete synonym of `eq'.
  7529. ... GE ... Obsolete synonym of `ge'.
  7530. ... GT ... Obsolete synonym of `gt'.
  7531. ... LE ... Obsolete synonym of `le'.
  7532. ... LT ... Obsolete synonym of `lt'.
  7533. ... NE ... Obsolete synonym of `ne'.
  7534. abs [ EXPR ] absolute value
  7535. ... and ... Low-precedence synonym for &&.
  7536. bless REFERENCE [, PACKAGE] Makes reference into an object of a package.
  7537. chomp [LIST] Strips $/ off LIST/$_. Returns count. Special if $/ eq ''!
  7538. chr Converts a number to char with the same ordinal.
  7539. else Part of if/unless {BLOCK} elsif {BLOCK} else {BLOCK}.
  7540. elsif Part of if/unless {BLOCK} elsif {BLOCK} else {BLOCK}.
  7541. exists $HASH{KEY} True if the key exists.
  7542. format [NAME] = Start of output format. Ended by a single dot (.) on a line.
  7543. formline PICTURE, LIST Backdoor into \"format\" processing.
  7544. glob EXPR Synonym of <EXPR>.
  7545. lc [ EXPR ] Returns lowercased EXPR.
  7546. lcfirst [ EXPR ] Returns EXPR with lower-cased first letter.
  7547. grep EXPR,LIST or grep {BLOCK} LIST Filters LIST via EXPR/BLOCK.
  7548. map EXPR, LIST or map {BLOCK} LIST Applies EXPR/BLOCK to elts of LIST.
  7549. no PACKAGE [SYMBOL1, ...] Partial reverse for `use'. Runs `unimport' method.
  7550. not ... Low-precedence synonym for ! - negation.
  7551. ... or ... Low-precedence synonym for ||.
  7552. pos STRING Set/Get end-position of the last match over this string, see \\G.
  7553. quotemeta [ EXPR ] Quote regexp metacharacters.
  7554. qw/WORD1 .../ Synonym of split('', 'WORD1 ...')
  7555. readline FH Synonym of <FH>.
  7556. readpipe CMD Synonym of `CMD`.
  7557. ref [ EXPR ] Type of EXPR when dereferenced.
  7558. sysopen FH, FILENAME, MODE [, PERM] (MODE is numeric, see Fcntl.)
  7559. tie VAR, PACKAGE, LIST Hide an object behind a simple Perl variable.
  7560. tied Returns internal object for a tied data.
  7561. uc [ EXPR ] Returns upcased EXPR.
  7562. ucfirst [ EXPR ] Returns EXPR with upcased first letter.
  7563. untie VAR Unlink an object from a simple Perl variable.
  7564. use PACKAGE [SYMBOL1, ...] Compile-time `require' with consequent `import'.
  7565. ... xor ... Low-precedence synonym for exclusive or.
  7566. prototype \\&SUB Returns prototype of the function given a reference.
  7567. =head1 Top-level heading.
  7568. =head2 Second-level heading.
  7569. =head3 Third-level heading (is there such?).
  7570. =over [ NUMBER ] Start list.
  7571. =item [ TITLE ] Start new item in the list.
  7572. =back End list.
  7573. =cut Switch from POD to Perl.
  7574. =pod Switch from Perl to POD.
  7575. ")
  7576. (defun cperl-switch-to-doc-buffer (&optional interactive)
  7577. "Go to the perl documentation buffer and insert the documentation."
  7578. (interactive "p")
  7579. (let ((buf (get-buffer-create cperl-doc-buffer)))
  7580. (if interactive
  7581. (switch-to-buffer-other-window buf)
  7582. (set-buffer buf))
  7583. (if (= (buffer-size) 0)
  7584. (progn
  7585. (insert (documentation-property 'cperl-short-docs
  7586. 'variable-documentation))
  7587. (setq buffer-read-only t)))))
  7588. (defun cperl-beautify-regexp-piece (b e embed level)
  7589. ;; b is before the starting delimiter, e before the ending
  7590. ;; e should be a marker, may be changed, but remains "correct".
  7591. ;; EMBED is nil if we process the whole REx.
  7592. ;; The REx is guaranteed to have //x
  7593. ;; LEVEL shows how many levels deep to go
  7594. ;; position at enter and at leave is not defined
  7595. (let (s c tmp (m (make-marker)) (m1 (make-marker)) c1 spaces inline code pos)
  7596. (if embed
  7597. (progn
  7598. (goto-char b)
  7599. (setq c (if (eq embed t) (current-indentation) (current-column)))
  7600. (cond ((looking-at "(\\?\\\\#") ; (?#) wrongly commented when //x-ing
  7601. (forward-char 2)
  7602. (delete-char 1)
  7603. (forward-char 1))
  7604. ((looking-at "(\\?[^a-zA-Z]")
  7605. (forward-char 3))
  7606. ((looking-at "(\\?") ; (?i)
  7607. (forward-char 2))
  7608. (t
  7609. (forward-char 1))))
  7610. (goto-char (1+ b))
  7611. (setq c (1- (current-column))))
  7612. (setq c1 (+ c (or cperl-regexp-indent-step cperl-indent-level)))
  7613. (or (looking-at "[ \t]*[\n#]")
  7614. (progn
  7615. (insert "\n")))
  7616. (goto-char e)
  7617. (beginning-of-line)
  7618. (if (re-search-forward "[^ \t]" e t)
  7619. (progn ; Something before the ending delimiter
  7620. (goto-char e)
  7621. (delete-horizontal-space)
  7622. (insert "\n")
  7623. (cperl-make-indent c)
  7624. (set-marker e (point))))
  7625. (goto-char b)
  7626. (end-of-line 2)
  7627. (while (< (point) (marker-position e))
  7628. (beginning-of-line)
  7629. (setq s (point)
  7630. inline t)
  7631. (skip-chars-forward " \t")
  7632. (delete-region s (point))
  7633. (cperl-make-indent c1)
  7634. (while (and
  7635. inline
  7636. (looking-at
  7637. (concat "\\([a-zA-Z0-9]+[^*+{?]\\)" ; 1 word
  7638. "\\|" ; Embedded variable
  7639. "\\$\\([a-zA-Z0-9_]+\\([[{]\\)?\\|[^\n \t)|]\\)" ; 2 3
  7640. "\\|" ; $ ^
  7641. "[$^]"
  7642. "\\|" ; simple-code simple-code*?
  7643. "\\(\\\\.\\|[^][()#|*+?\n]\\)\\([*+{?]\\??\\)?" ; 4 5
  7644. "\\|" ; Class
  7645. "\\(\\[\\)" ; 6
  7646. "\\|" ; Grouping
  7647. "\\((\\(\\?\\)?\\)" ; 7 8
  7648. "\\|" ; |
  7649. "\\(|\\)"))) ; 9
  7650. (goto-char (match-end 0))
  7651. (setq spaces t)
  7652. (cond ((match-beginning 1) ; Alphanum word + junk
  7653. (forward-char -1))
  7654. ((or (match-beginning 3) ; $ab[12]
  7655. (and (match-beginning 5) ; X* X+ X{2,3}
  7656. (eq (preceding-char) ?\{)))
  7657. (forward-char -1)
  7658. (forward-sexp 1))
  7659. ((and ; [], already syntaxified
  7660. (match-beginning 6)
  7661. cperl-regexp-scan
  7662. cperl-use-syntax-table-text-property)
  7663. (forward-char -1)
  7664. (forward-sexp 1)
  7665. (or (eq (preceding-char) ?\])
  7666. (error "[]-group not terminated"))
  7667. (re-search-forward
  7668. "\\=\\([*+?]\\|{[0-9]+\\(,[0-9]*\\)?}\\)\\??" e t))
  7669. ((match-beginning 6) ; []
  7670. (setq tmp (point))
  7671. (if (looking-at "\\^?\\]")
  7672. (goto-char (match-end 0)))
  7673. ;; XXXX POSIX classes?!
  7674. (while (and (not pos)
  7675. (re-search-forward "\\[:\\|\\]" e t))
  7676. (if (eq (preceding-char) ?:)
  7677. (or (re-search-forward ":\\]" e t)
  7678. (error "[:POSIX:]-group in []-group not terminated"))
  7679. (setq pos t)))
  7680. (or (eq (preceding-char) ?\])
  7681. (error "[]-group not terminated"))
  7682. (re-search-forward
  7683. "\\=\\([*+?]\\|{[0-9]+\\(,[0-9]*\\)?}\\)\\??" e t))
  7684. ((match-beginning 7) ; ()
  7685. (goto-char (match-beginning 0))
  7686. (setq pos (current-column))
  7687. (or (eq pos c1)
  7688. (progn
  7689. (delete-horizontal-space)
  7690. (insert "\n")
  7691. (cperl-make-indent c1)))
  7692. (setq tmp (point))
  7693. (forward-sexp 1)
  7694. ;; (or (forward-sexp 1)
  7695. ;; (progn
  7696. ;; (goto-char tmp)
  7697. ;; (error "()-group not terminated")))
  7698. (set-marker m (1- (point)))
  7699. (set-marker m1 (point))
  7700. (if (= level 1)
  7701. (if (progn ; indent rigidly if multiline
  7702. ;; In fact does not make a lot of sense, since
  7703. ;; the starting position can be already lost due
  7704. ;; to insertion of "\n" and " "
  7705. (goto-char tmp)
  7706. (search-forward "\n" m1 t))
  7707. (indent-rigidly (point) m1 (- c1 pos)))
  7708. (setq level (1- level))
  7709. (cond
  7710. ((not (match-beginning 8))
  7711. (cperl-beautify-regexp-piece tmp m t level))
  7712. ((eq (char-after (+ 2 tmp)) ?\{) ; Code
  7713. t)
  7714. ((eq (char-after (+ 2 tmp)) ?\() ; Conditional
  7715. (goto-char (+ 2 tmp))
  7716. (forward-sexp 1)
  7717. (cperl-beautify-regexp-piece (point) m t level))
  7718. ((eq (char-after (+ 2 tmp)) ?<) ; Lookbehind
  7719. (goto-char (+ 3 tmp))
  7720. (cperl-beautify-regexp-piece (point) m t level))
  7721. (t
  7722. (cperl-beautify-regexp-piece tmp m t level))))
  7723. (goto-char m1)
  7724. (cond ((looking-at "[*+?]\\??")
  7725. (goto-char (match-end 0)))
  7726. ((eq (following-char) ?\{)
  7727. (forward-sexp 1)
  7728. (if (eq (following-char) ?\?)
  7729. (forward-char))))
  7730. (skip-chars-forward " \t")
  7731. (setq spaces nil)
  7732. (if (looking-at "[#\n]")
  7733. (progn
  7734. (or (eolp) (indent-for-comment))
  7735. (beginning-of-line 2))
  7736. (delete-horizontal-space)
  7737. (insert "\n"))
  7738. (end-of-line)
  7739. (setq inline nil))
  7740. ((match-beginning 9) ; |
  7741. (forward-char -1)
  7742. (setq tmp (point))
  7743. (beginning-of-line)
  7744. (if (re-search-forward "[^ \t]" tmp t)
  7745. (progn
  7746. (goto-char tmp)
  7747. (delete-horizontal-space)
  7748. (insert "\n"))
  7749. ;; first at line
  7750. (delete-region (point) tmp))
  7751. (cperl-make-indent c)
  7752. (forward-char 1)
  7753. (skip-chars-forward " \t")
  7754. (setq spaces nil)
  7755. (if (looking-at "[#\n]")
  7756. (beginning-of-line 2)
  7757. (delete-horizontal-space)
  7758. (insert "\n"))
  7759. (end-of-line)
  7760. (setq inline nil)))
  7761. (or (looking-at "[ \t\n]")
  7762. (not spaces)
  7763. (insert " "))
  7764. (skip-chars-forward " \t"))
  7765. (or (looking-at "[#\n]")
  7766. (error "Unknown code `%s' in a regexp"
  7767. (buffer-substring (point) (1+ (point)))))
  7768. (and inline (end-of-line 2)))
  7769. ;; Special-case the last line of group
  7770. (if (and (>= (point) (marker-position e))
  7771. (/= (current-indentation) c))
  7772. (progn
  7773. (beginning-of-line)
  7774. (cperl-make-indent c)))))
  7775. (defun cperl-make-regexp-x ()
  7776. ;; Returns position of the start
  7777. ;; XXX this is called too often! Need to cache the result!
  7778. (save-excursion
  7779. (or cperl-use-syntax-table-text-property
  7780. (error "I need to have a regexp marked!"))
  7781. ;; Find the start
  7782. (if (looking-at "\\s|")
  7783. nil ; good already
  7784. (if (or (looking-at "\\([smy]\\|qr\\)\\s|")
  7785. (and (eq (preceding-char) ?q)
  7786. (looking-at "\\(r\\)\\s|")))
  7787. (goto-char (match-end 1))
  7788. (re-search-backward "\\s|"))) ; Assume it is scanned already.
  7789. ;;(forward-char 1)
  7790. (let ((b (point)) (e (make-marker)) have-x delim (c (current-column))
  7791. (sub-p (eq (preceding-char) ?s)) s)
  7792. (forward-sexp 1)
  7793. (set-marker e (1- (point)))
  7794. (setq delim (preceding-char))
  7795. (if (and sub-p (eq delim (char-after (- (point) 2))))
  7796. (error "Possible s/blah// - do not know how to deal with"))
  7797. (if sub-p (forward-sexp 1))
  7798. (if (looking-at "\\sw*x")
  7799. (setq have-x t)
  7800. (insert "x"))
  7801. ;; Protect fragile " ", "#"
  7802. (if have-x nil
  7803. (goto-char (1+ b))
  7804. (while (re-search-forward "\\(\\=\\|[^\\\\]\\)\\(\\\\\\\\\\)*[ \t\n#]" e t) ; Need to include (?#) too?
  7805. (forward-char -1)
  7806. (insert "\\")
  7807. (forward-char 1)))
  7808. b)))
  7809. (defun cperl-beautify-regexp (&optional deep)
  7810. "Do it. (Experimental, may change semantics, recheck the result.)
  7811. We suppose that the regexp is scanned already."
  7812. (interactive "P")
  7813. (setq deep (if deep (prefix-numeric-value deep) -1))
  7814. (save-excursion
  7815. (goto-char (cperl-make-regexp-x))
  7816. (let ((b (point)) (e (make-marker)))
  7817. (forward-sexp 1)
  7818. (set-marker e (1- (point)))
  7819. (cperl-beautify-regexp-piece b e nil deep))))
  7820. (defun cperl-regext-to-level-start ()
  7821. "Goto start of an enclosing group in regexp.
  7822. We suppose that the regexp is scanned already."
  7823. (interactive)
  7824. (let ((limit (cperl-make-regexp-x)) done)
  7825. (while (not done)
  7826. (or (eq (following-char) ?\()
  7827. (search-backward "(" (1+ limit) t)
  7828. (error "Cannot find `(' which starts a group"))
  7829. (setq done
  7830. (save-excursion
  7831. (skip-chars-backward "\\")
  7832. (looking-at "\\(\\\\\\\\\\)*(")))
  7833. (or done (forward-char -1)))))
  7834. (defun cperl-contract-level ()
  7835. "Find an enclosing group in regexp and contract it.
  7836. \(Experimental, may change semantics, recheck the result.)
  7837. We suppose that the regexp is scanned already."
  7838. (interactive)
  7839. ;; (save-excursion ; Can't, breaks `cperl-contract-levels'
  7840. (cperl-regext-to-level-start)
  7841. (let ((b (point)) (e (make-marker)) c)
  7842. (forward-sexp 1)
  7843. (set-marker e (1- (point)))
  7844. (goto-char b)
  7845. (while (re-search-forward "\\(#\\)\\|\n" e 'to-end)
  7846. (cond
  7847. ((match-beginning 1) ; #-comment
  7848. (or c (setq c (current-indentation)))
  7849. (beginning-of-line 2) ; Skip
  7850. (cperl-make-indent c))
  7851. (t
  7852. (delete-char -1)
  7853. (just-one-space))))))
  7854. (defun cperl-contract-levels ()
  7855. "Find an enclosing group in regexp and contract all the kids.
  7856. \(Experimental, may change semantics, recheck the result.)
  7857. We suppose that the regexp is scanned already."
  7858. (interactive)
  7859. (save-excursion
  7860. (condition-case nil
  7861. (cperl-regext-to-level-start)
  7862. (error ; We are outside outermost group
  7863. (goto-char (cperl-make-regexp-x))))
  7864. (let ((b (point)) (e (make-marker)) s c)
  7865. (forward-sexp 1)
  7866. (set-marker e (1- (point)))
  7867. (goto-char (1+ b))
  7868. (while (re-search-forward "\\(\\\\\\\\\\)\\|(" e t)
  7869. (cond
  7870. ((match-beginning 1) ; Skip
  7871. nil)
  7872. (t ; Group
  7873. (cperl-contract-level)))))))
  7874. (defun cperl-beautify-level (&optional deep)
  7875. "Find an enclosing group in regexp and beautify it.
  7876. \(Experimental, may change semantics, recheck the result.)
  7877. We suppose that the regexp is scanned already."
  7878. (interactive "P")
  7879. (setq deep (if deep (prefix-numeric-value deep) -1))
  7880. (save-excursion
  7881. (cperl-regext-to-level-start)
  7882. (let ((b (point)) (e (make-marker)))
  7883. (forward-sexp 1)
  7884. (set-marker e (1- (point)))
  7885. (cperl-beautify-regexp-piece b e 'level deep))))
  7886. (defun cperl-invert-if-unless-modifiers ()
  7887. "Change `B if A;' into `if (A) {B}' etc if possible.
  7888. \(Unfinished.)"
  7889. (interactive)
  7890. (let (A B pre-B post-B pre-if post-if pre-A post-A if-string
  7891. (w-rex "\\<\\(if\\|unless\\|while\\|until\\|for\\|foreach\\)\\>"))
  7892. (and (= (char-syntax (preceding-char)) ?w)
  7893. (forward-sexp -1))
  7894. (setq pre-if (point))
  7895. (cperl-backward-to-start-of-expr)
  7896. (setq pre-B (point))
  7897. (forward-sexp 1) ; otherwise forward-to-end-of-expr is NOP
  7898. (cperl-forward-to-end-of-expr)
  7899. (setq post-A (point))
  7900. (goto-char pre-if)
  7901. (or (looking-at w-rex)
  7902. ;; Find the position
  7903. (progn (goto-char post-A)
  7904. (while (and
  7905. (not (looking-at w-rex))
  7906. (> (point) pre-B))
  7907. (forward-sexp -1))
  7908. (setq pre-if (point))))
  7909. (or (looking-at w-rex)
  7910. (error "Can't find `if', `unless', `while', `until', `for' or `foreach'"))
  7911. ;; 1 B 2 ... 3 B-com ... 4 if 5 ... if-com 6 ... 7 A 8
  7912. (setq if-string (buffer-substring (match-beginning 0) (match-end 0)))
  7913. ;; First, simple part: find code boundaries
  7914. (forward-sexp 1)
  7915. (setq post-if (point))
  7916. (forward-sexp -2)
  7917. (forward-sexp 1)
  7918. (setq post-B (point))
  7919. (cperl-backward-to-start-of-expr)
  7920. (setq pre-B (point))
  7921. (setq B (buffer-substring pre-B post-B))
  7922. (goto-char pre-if)
  7923. (forward-sexp 2)
  7924. (forward-sexp -1)
  7925. ;; May be after $, @, $# etc of a variable
  7926. (skip-chars-backward "$@%#")
  7927. (setq pre-A (point))
  7928. (cperl-forward-to-end-of-expr)
  7929. (setq post-A (point))
  7930. (setq A (buffer-substring pre-A post-A))
  7931. ;; Now modify (from end, to not break the stuff)
  7932. (skip-chars-forward " \t;")
  7933. (delete-region pre-A (point)) ; we move to pre-A
  7934. (insert "\n" B ";\n}")
  7935. (and (looking-at "[ \t]*#") (cperl-indent-for-comment))
  7936. (delete-region pre-if post-if)
  7937. (delete-region pre-B post-B)
  7938. (goto-char pre-B)
  7939. (insert if-string " (" A ") {")
  7940. (setq post-B (point))
  7941. (if (looking-at "[ \t]+$")
  7942. (delete-horizontal-space)
  7943. (if (looking-at "[ \t]*#")
  7944. (cperl-indent-for-comment)
  7945. (just-one-space)))
  7946. (forward-line 1)
  7947. (if (looking-at "[ \t]*$")
  7948. (progn ; delete line
  7949. (delete-horizontal-space)
  7950. (delete-region (point) (1+ (point)))))
  7951. (cperl-indent-line)
  7952. (goto-char (1- post-B))
  7953. (forward-sexp 1)
  7954. (cperl-indent-line)
  7955. (goto-char pre-B)))
  7956. (defun cperl-invert-if-unless ()
  7957. "Change `if (A) {B}' into `B if A;' etc (or visa versa) if possible.
  7958. If the cursor is not on the leading keyword of the BLOCK flavor of
  7959. construct, will assume it is the STATEMENT flavor, so will try to find
  7960. the appropriate statement modifier."
  7961. (interactive)
  7962. (and (= (char-syntax (preceding-char)) ?w)
  7963. (forward-sexp -1))
  7964. (if (looking-at "\\<\\(if\\|unless\\|while\\|until\\|for\\|foreach\\)\\>")
  7965. (let ((pre-if (point))
  7966. pre-A post-A pre-B post-B A B state p end-B-code is-block B-comment
  7967. (if-string (buffer-substring (match-beginning 0) (match-end 0))))
  7968. (forward-sexp 2)
  7969. (setq post-A (point))
  7970. (forward-sexp -1)
  7971. (setq pre-A (point))
  7972. (setq is-block (and (eq (following-char) ?\( )
  7973. (save-excursion
  7974. (condition-case nil
  7975. (progn
  7976. (forward-sexp 2)
  7977. (forward-sexp -1)
  7978. (eq (following-char) ?\{ ))
  7979. (error nil)))))
  7980. (if is-block
  7981. (progn
  7982. (goto-char post-A)
  7983. (forward-sexp 1)
  7984. (setq post-B (point))
  7985. (forward-sexp -1)
  7986. (setq pre-B (point))
  7987. (if (and (eq (following-char) ?\{ )
  7988. (progn
  7989. (cperl-backward-to-noncomment post-A)
  7990. (eq (preceding-char) ?\) )))
  7991. (if (condition-case nil
  7992. (progn
  7993. (goto-char post-B)
  7994. (forward-sexp 1)
  7995. (forward-sexp -1)
  7996. (looking-at "\\<els\\(e\\|if\\)\\>"))
  7997. (error nil))
  7998. (error
  7999. "`%s' (EXPR) {BLOCK} with `else'/`elsif'" if-string)
  8000. (goto-char (1- post-B))
  8001. (cperl-backward-to-noncomment pre-B)
  8002. (if (eq (preceding-char) ?\;)
  8003. (forward-char -1))
  8004. (setq end-B-code (point))
  8005. (goto-char pre-B)
  8006. (while (re-search-forward "\\<\\(for\\|foreach\\|if\\|unless\\|while\\|until\\)\\>\\|;" end-B-code t)
  8007. (setq p (match-beginning 0)
  8008. A (buffer-substring p (match-end 0))
  8009. state (parse-partial-sexp pre-B p))
  8010. (or (nth 3 state)
  8011. (nth 4 state)
  8012. (nth 5 state)
  8013. (error "`%s' inside `%s' BLOCK" A if-string))
  8014. (goto-char (match-end 0)))
  8015. ;; Finally got it
  8016. (goto-char (1+ pre-B))
  8017. (skip-chars-forward " \t\n")
  8018. (setq B (buffer-substring (point) end-B-code))
  8019. (goto-char end-B-code)
  8020. (or (looking-at ";?[ \t\n]*}")
  8021. (progn
  8022. (skip-chars-forward "; \t\n")
  8023. (setq B-comment
  8024. (buffer-substring (point) (1- post-B)))))
  8025. (and (equal B "")
  8026. (setq B "1"))
  8027. (goto-char (1- post-A))
  8028. (cperl-backward-to-noncomment pre-A)
  8029. (or (looking-at "[ \t\n]*)")
  8030. (goto-char (1- post-A)))
  8031. (setq p (point))
  8032. (goto-char (1+ pre-A))
  8033. (skip-chars-forward " \t\n")
  8034. (setq A (buffer-substring (point) p))
  8035. (delete-region pre-B post-B)
  8036. (delete-region pre-A post-A)
  8037. (goto-char pre-if)
  8038. (insert B " ")
  8039. (and B-comment (insert B-comment " "))
  8040. (just-one-space)
  8041. (forward-word 1)
  8042. (setq pre-A (point))
  8043. (insert " " A ";")
  8044. (delete-horizontal-space)
  8045. (setq post-B (point))
  8046. (if (looking-at "#")
  8047. (indent-for-comment))
  8048. (goto-char post-B)
  8049. (forward-char -1)
  8050. (delete-horizontal-space)
  8051. (goto-char pre-A)
  8052. (just-one-space)
  8053. (goto-char pre-if)
  8054. (setq pre-A (set-marker (make-marker) pre-A))
  8055. (while (<= (point) (marker-position pre-A))
  8056. (cperl-indent-line)
  8057. (forward-line 1))
  8058. (goto-char (marker-position pre-A))
  8059. (if B-comment
  8060. (progn
  8061. (forward-line -1)
  8062. (indent-for-comment)
  8063. (goto-char (marker-position pre-A)))))
  8064. (error "`%s' (EXPR) not with an {BLOCK}" if-string)))
  8065. ;; (error "`%s' not with an (EXPR)" if-string)
  8066. (forward-sexp -1)
  8067. (cperl-invert-if-unless-modifiers)))
  8068. ;;(error "Not at `if', `unless', `while', `until', `for' or `foreach'")
  8069. (cperl-invert-if-unless-modifiers)))
  8070. ;;; By Anthony Foiani <afoiani@uswest.com>
  8071. ;;; Getting help on modules in C-h f ?
  8072. ;;; This is a modified version of `man'.
  8073. ;;; Need to teach it how to lookup functions
  8074. ;;;###autoload
  8075. (defun cperl-perldoc (word)
  8076. "Run `perldoc' on WORD."
  8077. (interactive
  8078. (list (let* ((default-entry (cperl-word-at-point))
  8079. (input (read-string
  8080. (format "perldoc entry%s: "
  8081. (if (string= default-entry "")
  8082. ""
  8083. (format " (default %s)" default-entry))))))
  8084. (if (string= input "")
  8085. (if (string= default-entry "")
  8086. (error "No perldoc args given")
  8087. default-entry)
  8088. input))))
  8089. (require 'man)
  8090. (let* ((case-fold-search nil)
  8091. (is-func (and
  8092. (string-match "^[a-z]+$" word)
  8093. (string-match (concat "^" word "\\>")
  8094. (documentation-property
  8095. 'cperl-short-docs
  8096. 'variable-documentation))))
  8097. (Man-switches "")
  8098. (manual-program (if is-func "perldoc -f" "perldoc")))
  8099. (cond
  8100. ((featurep 'xemacs)
  8101. (let ((Manual-program "perldoc")
  8102. (Manual-switches (if is-func (list "-f"))))
  8103. (manual-entry word)))
  8104. (t
  8105. (Man-getpage-in-background word)))))
  8106. ;;;###autoload
  8107. (defun cperl-perldoc-at-point ()
  8108. "Run a `perldoc' on the word around point."
  8109. (interactive)
  8110. (cperl-perldoc (cperl-word-at-point)))
  8111. (defcustom pod2man-program "pod2man"
  8112. "*File name for `pod2man'."
  8113. :type 'file
  8114. :group 'cperl)
  8115. ;;; By Nick Roberts <Nick.Roberts@src.bae.co.uk> (with changes)
  8116. (defun cperl-pod-to-manpage ()
  8117. "Create a virtual manpage in Emacs from the Perl Online Documentation."
  8118. (interactive)
  8119. (require 'man)
  8120. (let* ((pod2man-args (concat buffer-file-name " | nroff -man "))
  8121. (bufname (concat "Man " buffer-file-name))
  8122. (buffer (generate-new-buffer bufname)))
  8123. (with-current-buffer buffer
  8124. (let ((process-environment (copy-sequence process-environment)))
  8125. ;; Prevent any attempt to use display terminal fanciness.
  8126. (setenv "TERM" "dumb")
  8127. (set-process-sentinel
  8128. (start-process pod2man-program buffer "sh" "-c"
  8129. (format (cperl-pod2man-build-command) pod2man-args))
  8130. 'Man-bgproc-sentinel)))))
  8131. ;;; Updated version by him too
  8132. (defun cperl-build-manpage ()
  8133. "Create a virtual manpage in Emacs from the POD in the file."
  8134. (interactive)
  8135. (require 'man)
  8136. (cond
  8137. ((featurep 'xemacs)
  8138. (let ((Manual-program "perldoc"))
  8139. (manual-entry buffer-file-name)))
  8140. (t
  8141. (let* ((manual-program "perldoc")
  8142. (Man-switches ""))
  8143. (Man-getpage-in-background buffer-file-name)))))
  8144. (defun cperl-pod2man-build-command ()
  8145. "Builds the entire background manpage and cleaning command."
  8146. (let ((command (concat pod2man-program " %s 2>/dev/null"))
  8147. (flist (and (boundp 'Man-filter-list) Man-filter-list)))
  8148. (while (and flist (car flist))
  8149. (let ((pcom (car (car flist)))
  8150. (pargs (cdr (car flist))))
  8151. (setq command
  8152. (concat command " | " pcom " "
  8153. (mapconcat (lambda (phrase)
  8154. (if (not (stringp phrase))
  8155. (error "Malformed Man-filter-list"))
  8156. phrase)
  8157. pargs " ")))
  8158. (setq flist (cdr flist))))
  8159. command))
  8160. (defun cperl-next-interpolated-REx-1 ()
  8161. "Move point to next REx which has interpolated parts without //o.
  8162. Skips RExes consisting of one interpolated variable.
  8163. Note that skipped RExen are not performance hits."
  8164. (interactive "")
  8165. (cperl-next-interpolated-REx 1))
  8166. (defun cperl-next-interpolated-REx-0 ()
  8167. "Move point to next REx which has interpolated parts without //o."
  8168. (interactive "")
  8169. (cperl-next-interpolated-REx 0))
  8170. (defun cperl-next-interpolated-REx (&optional skip beg limit)
  8171. "Move point to next REx which has interpolated parts.
  8172. SKIP is a list of possible types to skip, BEG and LIMIT are the starting
  8173. point and the limit of search (default to point and end of buffer).
  8174. SKIP may be a number, then it behaves as list of numbers up to SKIP; this
  8175. semantic may be used as a numeric argument.
  8176. Types are 0 for / $rex /o (interpolated once), 1 for /$rex/ (if $rex is
  8177. a result of qr//, this is not a performance hit), t for the rest."
  8178. (interactive "P")
  8179. (if (numberp skip) (setq skip (list 0 skip)))
  8180. (or beg (setq beg (point)))
  8181. (or limit (setq limit (point-max))) ; needed for n-s-p-c
  8182. (let (pp)
  8183. (and (eq (get-text-property beg 'syntax-type) 'string)
  8184. (setq beg (next-single-property-change beg 'syntax-type nil limit)))
  8185. (cperl-map-pods-heres
  8186. (function (lambda (s e p)
  8187. (if (memq (get-text-property s 'REx-interpolated) skip)
  8188. t
  8189. (setq pp s)
  8190. nil))) ; nil stops
  8191. 'REx-interpolated beg limit)
  8192. (if pp (goto-char pp)
  8193. (message "No more interpolated REx"))))
  8194. ;;; Initial version contributed by Trey Belew
  8195. (defun cperl-here-doc-spell (&optional beg end)
  8196. "Spell-check HERE-documents in the Perl buffer.
  8197. If a region is highlighted, restricts to the region."
  8198. (interactive "")
  8199. (cperl-pod-spell t beg end))
  8200. (defun cperl-pod-spell (&optional do-heres beg end)
  8201. "Spell-check POD documentation.
  8202. If invoked with prefix argument, will do HERE-DOCs instead.
  8203. If a region is highlighted, restricts to the region."
  8204. (interactive "P")
  8205. (save-excursion
  8206. (let (beg end)
  8207. (if (cperl-mark-active)
  8208. (setq beg (min (mark) (point))
  8209. end (max (mark) (point)))
  8210. (setq beg (point-min)
  8211. end (point-max)))
  8212. (cperl-map-pods-heres (function
  8213. (lambda (s e p)
  8214. (if do-heres
  8215. (setq e (save-excursion
  8216. (goto-char e)
  8217. (forward-line -1)
  8218. (point))))
  8219. (ispell-region s e)
  8220. t))
  8221. (if do-heres 'here-doc-group 'in-pod)
  8222. beg end))))
  8223. (defun cperl-map-pods-heres (func &optional prop s end)
  8224. "Executes a function over regions of pods or here-documents.
  8225. PROP is the text-property to search for; default to `in-pod'. Stop when
  8226. function returns nil."
  8227. (let (pos posend has-prop (cont t))
  8228. (or prop (setq prop 'in-pod))
  8229. (or s (setq s (point-min)))
  8230. (or end (setq end (point-max)))
  8231. (cperl-update-syntaxification end end)
  8232. (save-excursion
  8233. (goto-char (setq pos s))
  8234. (while (and cont (< pos end))
  8235. (setq has-prop (get-text-property pos prop))
  8236. (setq posend (next-single-property-change pos prop nil end))
  8237. (and has-prop
  8238. (setq cont (funcall func pos posend prop)))
  8239. (setq pos posend)))))
  8240. ;;; Based on code by Masatake YAMATO:
  8241. (defun cperl-get-here-doc-region (&optional pos pod)
  8242. "Return HERE document region around the point.
  8243. Return nil if the point is not in a HERE document region. If POD is non-nil,
  8244. will return a POD section if point is in a POD section."
  8245. (or pos (setq pos (point)))
  8246. (cperl-update-syntaxification pos pos)
  8247. (if (or (eq 'here-doc (get-text-property pos 'syntax-type))
  8248. (and pod
  8249. (eq 'pod (get-text-property pos 'syntax-type))))
  8250. (let ((b (cperl-beginning-of-property pos 'syntax-type))
  8251. (e (next-single-property-change pos 'syntax-type)))
  8252. (cons b (or e (point-max))))))
  8253. (defun cperl-narrow-to-here-doc (&optional pos)
  8254. "Narrows editing region to the HERE-DOC at POS.
  8255. POS defaults to the point."
  8256. (interactive "d")
  8257. (or pos (setq pos (point)))
  8258. (let ((p (cperl-get-here-doc-region pos)))
  8259. (or p (error "Not inside a HERE document"))
  8260. (narrow-to-region (car p) (cdr p))
  8261. (message
  8262. "When you are finished with narrow editing, type C-x n w")))
  8263. (defun cperl-select-this-pod-or-here-doc (&optional pos)
  8264. "Select the HERE-DOC (or POD section) at POS.
  8265. POS defaults to the point."
  8266. (interactive "d")
  8267. (let ((p (cperl-get-here-doc-region pos t)))
  8268. (if p
  8269. (progn
  8270. (goto-char (car p))
  8271. (push-mark (cdr p) nil t)) ; Message, activate in transient-mode
  8272. (message "I do not think POS is in POD or a HERE-doc..."))))
  8273. (defun cperl-facemenu-add-face-function (face end)
  8274. "A callback to process user-initiated font-change requests.
  8275. Translates `bold', `italic', and `bold-italic' requests to insertion of
  8276. corresponding POD directives, and `underline' to C<> POD directive.
  8277. Such requests are usually bound to M-o LETTER."
  8278. (or (get-text-property (point) 'in-pod)
  8279. (error "Faces can only be set within POD"))
  8280. (setq facemenu-end-add-face (if (eq face 'bold-italic) ">>" ">"))
  8281. (cdr (or (assq face '((bold . "B<")
  8282. (italic . "I<")
  8283. (bold-italic . "B<I<")
  8284. (underline . "C<")))
  8285. (error "Face %s not configured for cperl-mode"
  8286. face))))
  8287. (defun cperl-time-fontification (&optional l step lim)
  8288. "Times how long it takes to do incremental fontification in a region.
  8289. L is the line to start at, STEP is the number of lines to skip when
  8290. doing next incremental fontification, LIM is the maximal number of
  8291. incremental fontification to perform. Messages are accumulated in
  8292. *Messages* buffer.
  8293. May be used for pinpointing which construct slows down buffer fontification:
  8294. start with default arguments, then refine the slowdown regions."
  8295. (interactive "nLine to start at: \nnStep to do incremental fontification: ")
  8296. (or l (setq l 1))
  8297. (or step (setq step 500))
  8298. (or lim (setq lim 40))
  8299. (let* ((timems (function (lambda ()
  8300. (let ((tt (current-time)))
  8301. (+ (* 1000 (nth 1 tt)) (/ (nth 2 tt) 1000))))))
  8302. (tt (funcall timems)) (c 0) delta tot)
  8303. (goto-char (point-min))
  8304. (forward-line (1- l))
  8305. (cperl-mode)
  8306. (setq tot (- (- tt (setq tt (funcall timems)))))
  8307. (message "cperl-mode at %s: %s" l tot)
  8308. (while (and (< c lim) (not (eobp)))
  8309. (forward-line step)
  8310. (setq l (+ l step))
  8311. (setq c (1+ c))
  8312. (cperl-update-syntaxification (point) (point))
  8313. (setq delta (- (- tt (setq tt (funcall timems)))) tot (+ tot delta))
  8314. (message "to %s:%6s,%7s" l delta tot))
  8315. tot))
  8316. (defvar font-lock-cache-position)
  8317. (defun cperl-emulate-lazy-lock (&optional window-size)
  8318. "Emulate `lazy-lock' without `condition-case', so `debug-on-error' works.
  8319. Start fontifying the buffer from the start (or end) using the given
  8320. WINDOW-SIZE (units is lines). Negative WINDOW-SIZE starts at end, and
  8321. goes backwards; default is -50. This function is not CPerl-specific; it
  8322. may be used to debug problems with delayed incremental fontification."
  8323. (interactive
  8324. "nSize of window for incremental fontification, negative goes backwards: ")
  8325. (or window-size (setq window-size -50))
  8326. (let ((pos (if (> window-size 0)
  8327. (point-min)
  8328. (point-max)))
  8329. p)
  8330. (goto-char pos)
  8331. (normal-mode)
  8332. ;; Why needed??? With older font-locks???
  8333. (set (make-local-variable 'font-lock-cache-position) (make-marker))
  8334. (while (if (> window-size 0)
  8335. (< pos (point-max))
  8336. (> pos (point-min)))
  8337. (setq p (progn
  8338. (forward-line window-size)
  8339. (point)))
  8340. (font-lock-fontify-region (min p pos) (max p pos))
  8341. (setq pos p))))
  8342. (defun cperl-lazy-install ()) ; Avoid a warning
  8343. (defun cperl-lazy-unstall ()) ; Avoid a warning
  8344. (if (fboundp 'run-with-idle-timer)
  8345. (progn
  8346. (defvar cperl-help-shown nil
  8347. "Non-nil means that the help was already shown now.")
  8348. (defvar cperl-lazy-installed nil
  8349. "Non-nil means that the lazy-help handlers are installed now.")
  8350. (defun cperl-lazy-install ()
  8351. "Switches on Auto-Help on Perl constructs (put in the message area).
  8352. Delay of auto-help controlled by `cperl-lazy-help-time'."
  8353. (interactive)
  8354. (make-local-variable 'cperl-help-shown)
  8355. (if (and (cperl-val 'cperl-lazy-help-time)
  8356. (not cperl-lazy-installed))
  8357. (progn
  8358. (add-hook 'post-command-hook 'cperl-lazy-hook)
  8359. (run-with-idle-timer
  8360. (cperl-val 'cperl-lazy-help-time 1000000 5)
  8361. t
  8362. 'cperl-get-help-defer)
  8363. (setq cperl-lazy-installed t))))
  8364. (defun cperl-lazy-unstall ()
  8365. "Switches off Auto-Help on Perl constructs (put in the message area).
  8366. Delay of auto-help controlled by `cperl-lazy-help-time'."
  8367. (interactive)
  8368. (remove-hook 'post-command-hook 'cperl-lazy-hook)
  8369. (cancel-function-timers 'cperl-get-help-defer)
  8370. (setq cperl-lazy-installed nil))
  8371. (defun cperl-lazy-hook ()
  8372. (setq cperl-help-shown nil))
  8373. (defun cperl-get-help-defer ()
  8374. (if (not (memq major-mode '(perl-mode cperl-mode))) nil
  8375. (let ((cperl-message-on-help-error nil) (cperl-help-from-timer t))
  8376. (cperl-get-help)
  8377. (setq cperl-help-shown t))))
  8378. (cperl-lazy-install)))
  8379. ;;; Plug for wrong font-lock:
  8380. (defun cperl-font-lock-unfontify-region-function (beg end)
  8381. (let* ((modified (buffer-modified-p)) (buffer-undo-list t)
  8382. (inhibit-read-only t) (inhibit-point-motion-hooks t)
  8383. before-change-functions after-change-functions
  8384. deactivate-mark buffer-file-name buffer-file-truename)
  8385. (remove-text-properties beg end '(face nil))
  8386. (if (and (not modified) (buffer-modified-p))
  8387. (set-buffer-modified-p nil))))
  8388. (defun cperl-font-lock-fontify-region-function (beg end loudly)
  8389. "Extends the region to safe positions, then calls the default function.
  8390. Newer `font-lock's can do it themselves.
  8391. We unwind only as far as needed for fontification. Syntaxification may
  8392. do extra unwind via `cperl-unwind-to-safe'."
  8393. (save-excursion
  8394. (goto-char beg)
  8395. (while (and beg
  8396. (progn
  8397. (beginning-of-line)
  8398. (eq (get-text-property (setq beg (point)) 'syntax-type)
  8399. 'multiline)))
  8400. (if (setq beg (cperl-beginning-of-property beg 'syntax-type))
  8401. (goto-char beg)))
  8402. (setq beg (point))
  8403. (goto-char end)
  8404. (while (and end
  8405. (progn
  8406. (or (bolp) (condition-case nil
  8407. (forward-line 1)
  8408. (error nil)))
  8409. (eq (get-text-property (setq end (point)) 'syntax-type)
  8410. 'multiline)))
  8411. (setq end (next-single-property-change end 'syntax-type nil (point-max)))
  8412. (goto-char end))
  8413. (setq end (point)))
  8414. (font-lock-default-fontify-region beg end loudly))
  8415. (defvar cperl-d-l nil)
  8416. (defun cperl-fontify-syntaxically (end)
  8417. ;; Some vars for debugging only
  8418. ;; (message "Syntaxifying...")
  8419. (let ((dbg (point)) (iend end) (idone cperl-syntax-done-to)
  8420. (istate (car cperl-syntax-state))
  8421. start from-start edebug-backtrace-buffer)
  8422. (if (eq cperl-syntaxify-by-font-lock 'backtrace)
  8423. (progn
  8424. (require 'edebug)
  8425. (let ((f 'edebug-backtrace))
  8426. (funcall f)))) ; Avoid compile-time warning
  8427. (or cperl-syntax-done-to
  8428. (setq cperl-syntax-done-to (point-min)
  8429. from-start t))
  8430. (setq start (if (and cperl-hook-after-change
  8431. (not from-start))
  8432. cperl-syntax-done-to ; Fontify without change; ignore start
  8433. ;; Need to forget what is after `start'
  8434. (min cperl-syntax-done-to (point))))
  8435. (goto-char start)
  8436. (beginning-of-line)
  8437. (setq start (point))
  8438. (and cperl-syntaxify-unwind
  8439. (setq end (cperl-unwind-to-safe t end)
  8440. start (point)))
  8441. (and (> end start)
  8442. (setq cperl-syntax-done-to start) ; In case what follows fails
  8443. (cperl-find-pods-heres start end t nil t))
  8444. (if (memq cperl-syntaxify-by-font-lock '(backtrace message))
  8445. (message "Syxify req=%s..%s actual=%s..%s done-to: %s=>%s statepos: %s=>%s"
  8446. dbg iend start end idone cperl-syntax-done-to
  8447. istate (car cperl-syntax-state))) ; For debugging
  8448. nil)) ; Do not iterate
  8449. (defun cperl-fontify-update (end)
  8450. (let ((pos (point-min)) prop posend)
  8451. (setq end (point-max))
  8452. (while (< pos end)
  8453. (setq prop (get-text-property pos 'cperl-postpone)
  8454. posend (next-single-property-change pos 'cperl-postpone nil end))
  8455. (and prop (put-text-property pos posend (car prop) (cdr prop)))
  8456. (setq pos posend)))
  8457. nil) ; Do not iterate
  8458. (defun cperl-fontify-update-bad (end)
  8459. ;; Since fontification happens with different region than syntaxification,
  8460. ;; do to the end of buffer, not to END;;; likewise, start earlier if needed
  8461. (let* ((pos (point)) (prop (get-text-property pos 'cperl-postpone)) posend)
  8462. (if prop
  8463. (setq pos (or (cperl-beginning-of-property
  8464. (cperl-1+ pos) 'cperl-postpone)
  8465. (point-min))))
  8466. (while (< pos end)
  8467. (setq posend (next-single-property-change pos 'cperl-postpone))
  8468. (and prop (put-text-property pos posend (car prop) (cdr prop)))
  8469. (setq pos posend)
  8470. (setq prop (get-text-property pos 'cperl-postpone))))
  8471. nil) ; Do not iterate
  8472. ;; Called when any modification is made to buffer text.
  8473. (defun cperl-after-change-function (beg end old-len)
  8474. ;; We should have been informed about changes by `font-lock'. Since it
  8475. ;; does not inform as which calls are deferred, do it ourselves
  8476. (if cperl-syntax-done-to
  8477. (setq cperl-syntax-done-to (min cperl-syntax-done-to beg))))
  8478. (defun cperl-update-syntaxification (from to)
  8479. (cond
  8480. ((not cperl-use-syntax-table-text-property) nil)
  8481. ((fboundp 'syntax-propertize) (syntax-propertize to))
  8482. ((and cperl-syntaxify-by-font-lock
  8483. (or (null cperl-syntax-done-to)
  8484. (< cperl-syntax-done-to to)))
  8485. (save-excursion
  8486. (goto-char from)
  8487. (cperl-fontify-syntaxically to)))))
  8488. (defvar cperl-version
  8489. (let ((v "Revision: 6.2"))
  8490. (string-match ":\\s *\\([0-9.]+\\)" v)
  8491. (substring v (match-beginning 1) (match-end 1)))
  8492. "Version of IZ-supported CPerl package this file is based on.")
  8493. (provide 'cperl-mode)
  8494. ;;; cperl-mode.el ends here