cperl-mode.el 323 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007
  1. ;;; cperl-mode.el --- Perl code editing commands for Emacs
  2. ;; Copyright (C) 1985-1987, 1991-2015 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. (make-obsolete-variable 'cperl-under-as-char 'superword-mode "24.4")
  481. (defcustom cperl-extra-perl-args ""
  482. "*Extra arguments to use when starting Perl.
  483. Currently used with `cperl-check-syntax' only."
  484. :type 'string
  485. :group 'cperl)
  486. (defcustom cperl-message-electric-keyword t
  487. "*Non-nil means that the `cperl-electric-keyword' prints a help message."
  488. :type 'boolean
  489. :group 'cperl-help-system)
  490. (defcustom cperl-indent-region-fix-constructs 1
  491. "*Amount of space to insert between `}' and `else' or `elsif'
  492. in `cperl-indent-region'. Set to nil to leave as is. Values other
  493. than 1 and nil will probably not work."
  494. :type '(choice (const nil) (const 1))
  495. :group 'cperl-indentation-details)
  496. (defcustom cperl-break-one-line-blocks-when-indent t
  497. "*Non-nil means that one-line if/unless/while/until/for/foreach BLOCKs
  498. need to be reformatted into multiline ones when indenting a region."
  499. :type 'boolean
  500. :group 'cperl-indentation-details)
  501. (defcustom cperl-fix-hanging-brace-when-indent t
  502. "*Non-nil means that BLOCK-end `}' may be put on a separate line
  503. when indenting a region.
  504. Braces followed by else/elsif/while/until are excepted."
  505. :type 'boolean
  506. :group 'cperl-indentation-details)
  507. (defcustom cperl-merge-trailing-else t
  508. "*Non-nil means that BLOCK-end `}' followed by else/elsif/continue
  509. may be merged to be on the same line when indenting a region."
  510. :type 'boolean
  511. :group 'cperl-indentation-details)
  512. (defcustom cperl-indent-parens-as-block nil
  513. "*Non-nil means that non-block ()-, {}- and []-groups are indented as blocks,
  514. but for trailing \",\" inside the group, which won't increase indentation.
  515. One should tune up `cperl-close-paren-offset' as well."
  516. :type 'boolean
  517. :group 'cperl-indentation-details)
  518. (defcustom cperl-syntaxify-by-font-lock
  519. (and cperl-can-font-lock
  520. (boundp 'parse-sexp-lookup-properties))
  521. "*Non-nil means that CPerl uses the `font-lock' routines for syntaxification."
  522. :type '(choice (const message) boolean)
  523. :group 'cperl-speed)
  524. (defcustom cperl-syntaxify-unwind
  525. t
  526. "*Non-nil means that CPerl unwinds to a start of a long construction
  527. when syntaxifying a chunk of buffer."
  528. :type 'boolean
  529. :group 'cperl-speed)
  530. (defcustom cperl-syntaxify-for-menu
  531. t
  532. "*Non-nil means that CPerl syntaxifies up to the point before showing menu.
  533. This way enabling/disabling of menu items is more correct."
  534. :type 'boolean
  535. :group 'cperl-speed)
  536. (defcustom cperl-ps-print-face-properties
  537. '((font-lock-keyword-face nil nil bold shadow)
  538. (font-lock-variable-name-face nil nil bold)
  539. (font-lock-function-name-face nil nil bold italic box)
  540. (font-lock-constant-face nil "LightGray" bold)
  541. (cperl-array-face nil "LightGray" bold underline)
  542. (cperl-hash-face nil "LightGray" bold italic underline)
  543. (font-lock-comment-face nil "LightGray" italic)
  544. (font-lock-string-face nil nil italic underline)
  545. (cperl-nonoverridable-face nil nil italic underline)
  546. (font-lock-type-face nil nil underline)
  547. (font-lock-warning-face nil "LightGray" bold italic box)
  548. (underline nil "LightGray" strikeout))
  549. "List given as an argument to `ps-extend-face-list' in `cperl-ps-print'."
  550. :type '(repeat (cons symbol
  551. (cons (choice (const nil) string)
  552. (cons (choice (const nil) string)
  553. (repeat symbol)))))
  554. :group 'cperl-faces)
  555. (defvar cperl-dark-background
  556. (cperl-choose-color "navy" "os2blue" "darkgreen"))
  557. (defvar cperl-dark-foreground
  558. (cperl-choose-color "orchid1" "orange"))
  559. (defface cperl-nonoverridable-face
  560. `((((class grayscale) (background light))
  561. (:background "Gray90" :slant italic :underline t))
  562. (((class grayscale) (background dark))
  563. (:foreground "Gray80" :slant italic :underline t :weight bold))
  564. (((class color) (background light))
  565. (:foreground "chartreuse3"))
  566. (((class color) (background dark))
  567. (:foreground ,cperl-dark-foreground))
  568. (t (:weight bold :underline t)))
  569. "Font Lock mode face used non-overridable keywords and modifiers of regexps."
  570. :group 'cperl-faces)
  571. (defface cperl-array-face
  572. `((((class grayscale) (background light))
  573. (:background "Gray90" :weight bold))
  574. (((class grayscale) (background dark))
  575. (:foreground "Gray80" :weight bold))
  576. (((class color) (background light))
  577. (:foreground "Blue" :background "lightyellow2" :weight bold))
  578. (((class color) (background dark))
  579. (:foreground "yellow" :background ,cperl-dark-background :weight bold))
  580. (t (:weight bold)))
  581. "Font Lock mode face used to highlight array names."
  582. :group 'cperl-faces)
  583. (defface cperl-hash-face
  584. `((((class grayscale) (background light))
  585. (:background "Gray90" :weight bold :slant italic))
  586. (((class grayscale) (background dark))
  587. (:foreground "Gray80" :weight bold :slant italic))
  588. (((class color) (background light))
  589. (:foreground "Red" :background "lightyellow2" :weight bold :slant italic))
  590. (((class color) (background dark))
  591. (:foreground "Red" :background ,cperl-dark-background :weight bold :slant italic))
  592. (t (:weight bold :slant italic)))
  593. "Font Lock mode face used to highlight hash names."
  594. :group 'cperl-faces)
  595. ;;; Short extra-docs.
  596. (defvar cperl-tips 'please-ignore-this-line
  597. "Get maybe newer version of this package from
  598. http://ilyaz.org/software/emacs
  599. Subdirectory `cperl-mode' may contain yet newer development releases and/or
  600. patches to related files.
  601. For best results apply to an older Emacs the patches from
  602. ftp://ftp.math.ohio-state.edu/pub/users/ilya/cperl-mode/patches
  603. \(this upgrades syntax-parsing abilities of Emacsen v19.34 and
  604. v20.2 up to the level of Emacs v20.3 - a must for a good Perl
  605. mode.) As of beginning of 2003, XEmacs may provide a similar ability.
  606. Get support packages choose-color.el (or font-lock-extra.el before
  607. 19.30), imenu-go.el from the same place. \(Look for other files there
  608. too... ;-). Get a patch for imenu.el in 19.29. Note that for 19.30 and
  609. later you should use choose-color.el *instead* of font-lock-extra.el
  610. \(and you will not get smart highlighting in C :-().
  611. Note that to enable Compile choices in the menu you need to install
  612. mode-compile.el.
  613. If your Emacs does not default to `cperl-mode' on Perl files, and you
  614. want it to: put the following into your .emacs file:
  615. (defalias \\='perl-mode \\='cperl-mode)
  616. Get perl5-info from
  617. $CPAN/doc/manual/info/perl5-old/perl5-info.tar.gz
  618. Also, one can generate a newer documentation running `pod2texi' converter
  619. $CPAN/doc/manual/info/perl5/pod2texi-0.1.tar.gz
  620. If you use imenu-go, run imenu on perl5-info buffer (you can do it
  621. from Perl menu). If many files are related, generate TAGS files from
  622. Tools/Tags submenu in Perl menu.
  623. If some class structure is too complicated, use Tools/Hierarchy-view
  624. from Perl menu, or hierarchic view of imenu. The second one uses the
  625. current buffer only, the first one requires generation of TAGS from
  626. Perl/Tools/Tags menu beforehand.
  627. Run Perl/Tools/Insert-spaces-if-needed to fix your lazy typing.
  628. Switch auto-help on/off with Perl/Tools/Auto-help.
  629. Though with contemporary Emaxen CPerl mode should maintain the correct
  630. parsing of Perl even when editing, sometimes it may be lost. Fix this by
  631. \\[normal-mode]
  632. In cases of more severe confusion sometimes it is helpful to do
  633. \\[load-library] cperl-mode RET
  634. \\[normal-mode]
  635. Before reporting (non-)problems look in the problem section of online
  636. micro-docs on what I know about CPerl problems.")
  637. (defvar cperl-problems 'please-ignore-this-line
  638. "Description of problems in CPerl mode.
  639. Some faces will not be shown on some versions of Emacs unless you
  640. install choose-color.el, available from
  641. http://ilyaz.org/software/emacs
  642. `fill-paragraph' on a comment may leave the point behind the
  643. paragraph. It also triggers a bug in some versions of Emacs (CPerl tries
  644. to detect it and bulk out).
  645. See documentation of a variable `cperl-problems-old-emaxen' for the
  646. problems which disappear if you upgrade Emacs to a reasonably new
  647. version (20.3 for Emacs, and those of 2004 for XEmacs).")
  648. (defvar cperl-problems-old-emaxen 'please-ignore-this-line
  649. "Description of problems in CPerl mode specific for older Emacs versions.
  650. Emacs had a _very_ restricted syntax parsing engine until version
  651. 20.1. Most problems below are corrected starting from this version of
  652. Emacs, and all of them should be fixed in version 20.3. (Or apply
  653. patches to Emacs 19.33/34 - see tips.) XEmacs was very backward in
  654. this respect (until 2003).
  655. Note that even with newer Emacsen in some very rare cases the details
  656. of interaction of `font-lock' and syntaxification may be not cleaned
  657. up yet. You may get slightly different colors basing on the order of
  658. fontification and syntaxification. Say, the initial faces is correct,
  659. but editing the buffer breaks this.
  660. Even with older Emacsen CPerl mode tries to corrects some Emacs
  661. misunderstandings, however, for efficiency reasons the degree of
  662. correction is different for different operations. The partially
  663. corrected problems are: POD sections, here-documents, regexps. The
  664. operations are: highlighting, indentation, electric keywords, electric
  665. braces.
  666. This may be confusing, since the regexp s#//#/#; may be highlighted
  667. as a comment, but it will be recognized as a regexp by the indentation
  668. code. Or the opposite case, when a POD section is highlighted, but
  669. may break the indentation of the following code (though indentation
  670. should work if the balance of delimiters is not broken by POD).
  671. The main trick (to make $ a \"backslash\") makes constructions like
  672. ${aaa} look like unbalanced braces. The only trick I can think of is
  673. to insert it as $ {aaa} (valid in perl5, not in perl4).
  674. Similar problems arise in regexps, when /(\\s|$)/ should be rewritten
  675. as /($|\\s)/. Note that such a transposition is not always possible.
  676. The solution is to upgrade your Emacs or patch an older one. Note
  677. that Emacs 20.2 has some bugs related to `syntax-table' text
  678. properties. Patches are available on the main CPerl download site,
  679. and on CPAN.
  680. If these bugs cannot be fixed on your machine (say, you have an inferior
  681. environment and cannot recompile), you may still disable all the fancy stuff
  682. via `cperl-use-syntax-table-text-property'.")
  683. (defvar cperl-praise 'please-ignore-this-line
  684. "Advantages of CPerl mode.
  685. 0) It uses the newest `syntax-table' property ;-);
  686. 1) It does 99% of Perl syntax correct (as opposed to 80-90% in Perl
  687. mode - but the latter number may have improved too in last years) even
  688. with old Emaxen which do not support `syntax-table' property.
  689. When using `syntax-table' property for syntax assist hints, it should
  690. handle 99.995% of lines correct - or somesuch. It automatically
  691. updates syntax assist hints when you edit your script.
  692. 2) It is generally believed to be \"the most user-friendly Emacs
  693. package\" whatever it may mean (I doubt that the people who say similar
  694. things tried _all_ the rest of Emacs ;-), but this was not a lonely
  695. voice);
  696. 3) Everything is customizable, one-by-one or in a big sweep;
  697. 4) It has many easily-accessible \"tools\":
  698. a) Can run program, check syntax, start debugger;
  699. b) Can lineup vertically \"middles\" of rows, like `=' in
  700. a = b;
  701. cc = d;
  702. c) Can insert spaces where this improves readability (in one
  703. interactive sweep over the buffer);
  704. d) Has support for imenu, including:
  705. 1) Separate unordered list of \"interesting places\";
  706. 2) Separate TOC of POD sections;
  707. 3) Separate list of packages;
  708. 4) Hierarchical view of methods in (sub)packages;
  709. 5) and functions (by the full name - with package);
  710. e) Has an interface to INFO docs for Perl; The interface is
  711. very flexible, including shrink-wrapping of
  712. documentation buffer/frame;
  713. f) Has a builtin list of one-line explanations for perl constructs.
  714. g) Can show these explanations if you stay long enough at the
  715. corresponding place (or on demand);
  716. h) Has an enhanced fontification (using 3 or 4 additional faces
  717. comparing to font-lock - basically, different
  718. namespaces in Perl have different colors);
  719. i) Can construct TAGS basing on its knowledge of Perl syntax,
  720. the standard menu has 6 different way to generate
  721. TAGS (if \"by directory\", .xs files - with C-language
  722. bindings - are included in the scan);
  723. j) Can build a hierarchical view of classes (via imenu) basing
  724. on generated TAGS file;
  725. k) Has electric parentheses, electric newlines, uses Abbrev
  726. for electric logical constructs
  727. while () {}
  728. with different styles of expansion (context sensitive
  729. to be not so bothering). Electric parentheses behave
  730. \"as they should\" in a presence of a visible region.
  731. l) Changes msb.el \"on the fly\" to insert a group \"Perl files\";
  732. m) Can convert from
  733. if (A) { B }
  734. to
  735. B if A;
  736. n) Highlights (by user-choice) either 3-delimiters constructs
  737. (such as tr/a/b/), or regular expressions and `y/tr';
  738. o) Highlights trailing whitespace;
  739. p) Is able to manipulate Perl Regular Expressions to ease
  740. conversion to a more readable form.
  741. q) Can ispell POD sections and HERE-DOCs.
  742. r) Understands comments and character classes inside regular
  743. expressions; can find matching () and [] in a regular expression.
  744. s) Allows indentation of //x-style regular expressions;
  745. t) Highlights different symbols in regular expressions according
  746. to their function; much less problems with backslashitis;
  747. u) Allows to find regular expressions which contain interpolated parts.
  748. 5) The indentation engine was very smart, but most of tricks may be
  749. not needed anymore with the support for `syntax-table' property. Has
  750. progress indicator for indentation (with `imenu' loaded).
  751. 6) Indent-region improves inline-comments as well; also corrects
  752. whitespace *inside* the conditional/loop constructs.
  753. 7) Fill-paragraph correctly handles multi-line comments;
  754. 8) Can switch to different indentation styles by one command, and restore
  755. the settings present before the switch.
  756. 9) When doing indentation of control constructs, may correct
  757. line-breaks/spacing between elements of the construct.
  758. 10) Uses a linear-time algorithm for indentation of regions (on Emaxen with
  759. capable syntax engines).
  760. 11) Syntax-highlight, indentation, sexp-recognition inside regular expressions.
  761. ")
  762. (defvar cperl-speed 'please-ignore-this-line
  763. "This is an incomplete compendium of what is available in other parts
  764. of CPerl documentation. (Please inform me if I skept anything.)
  765. There is a perception that CPerl is slower than alternatives. This part
  766. of documentation is designed to overcome this misconception.
  767. *By default* CPerl tries to enable the most comfortable settings.
  768. From most points of view, correctly working package is infinitely more
  769. comfortable than a non-correctly working one, thus by default CPerl
  770. prefers correctness over speed. Below is the guide how to change
  771. settings if your preferences are different.
  772. A) Speed of loading the file. When loading file, CPerl may perform a
  773. scan which indicates places which cannot be parsed by primitive Emacs
  774. syntax-parsing routines, and marks them up so that either
  775. A1) CPerl may work around these deficiencies (for big chunks, mostly
  776. PODs and HERE-documents), or
  777. A2) On capable Emaxen CPerl will use improved syntax-handling
  778. which reads mark-up hints directly.
  779. The scan in case A2 is much more comprehensive, thus may be slower.
  780. User can disable syntax-engine-helping scan of A2 by setting
  781. `cperl-use-syntax-table-text-property'
  782. variable to nil (if it is set to t).
  783. One can disable the scan altogether (both A1 and A2) by setting
  784. `cperl-pod-here-scan'
  785. to nil.
  786. B) Speed of editing operations.
  787. One can add a (minor) speedup to editing operations by setting
  788. `cperl-use-syntax-table-text-property'
  789. variable to nil (if it is set to t). This will disable
  790. syntax-engine-helping scan, thus will make many more Perl
  791. constructs be wrongly recognized by CPerl, thus may lead to
  792. wrongly matched parentheses, wrong indentation, etc.
  793. One can unset `cperl-syntaxify-unwind'. This might speed up editing
  794. of, say, long POD sections.")
  795. (defvar cperl-tips-faces 'please-ignore-this-line
  796. "CPerl mode uses following faces for highlighting:
  797. `cperl-array-face' Array names
  798. `cperl-hash-face' Hash names
  799. `font-lock-comment-face' Comments, PODs and whatever is considered
  800. syntactically to be not code
  801. `font-lock-constant-face' HERE-doc delimiters, labels, delimiters of
  802. 2-arg operators s/y/tr/ or of RExen,
  803. `font-lock-warning-face' Special-cased m// and s//foo/,
  804. `font-lock-function-name-face' _ as a target of a file tests, file tests,
  805. subroutine names at the moment of definition
  806. (except those conflicting with Perl operators),
  807. package names (when recognized), format names
  808. `font-lock-keyword-face' Control flow switch constructs, declarators
  809. `cperl-nonoverridable-face' Non-overridable keywords, modifiers of RExen
  810. `font-lock-string-face' Strings, qw() constructs, RExen, POD sections,
  811. literal parts and the terminator of formats
  812. and whatever is syntactically considered
  813. as string literals
  814. `font-lock-type-face' Overridable keywords
  815. `font-lock-variable-name-face' Variable declarations, indirect array and
  816. hash names, POD headers/item names
  817. `cperl-invalid-face' Trailing whitespace
  818. Note that in several situations the highlighting tries to inform about
  819. possible confusion, such as different colors for function names in
  820. declarations depending on what they (do not) override, or special cases
  821. m// and s/// which do not do what one would expect them to do.
  822. Help with best setup of these faces for printout requested (for each of
  823. the faces: please specify bold, italic, underline, shadow and box.)
  824. In regular expressions (including character classes):
  825. `font-lock-string-face' \"Normal\" stuff and non-0-length constructs
  826. `font-lock-constant-face': Delimiters
  827. `font-lock-warning-face' Special-cased m// and s//foo/,
  828. Mismatched closing delimiters, parens
  829. we couldn't match, misplaced quantifiers,
  830. unrecognized escape sequences
  831. `cperl-nonoverridable-face' Modifiers, as gism in m/REx/gism
  832. `font-lock-type-face' escape sequences with arguments (\\x \\23 \\p \\N)
  833. and others match-a-char escape sequences
  834. `font-lock-keyword-face' Capturing parens, and |
  835. `font-lock-function-name-face' Special symbols: $ ^ . [ ] [^ ] (?{ }) (??{ })
  836. \"Range -\" in character classes
  837. `font-lock-builtin-face' \"Remaining\" 0-length constructs, multipliers
  838. ?+*{}, not-capturing parens, leading
  839. backslashes of escape sequences
  840. `font-lock-variable-name-face' Interpolated constructs, embedded code,
  841. POSIX classes (inside charclasses)
  842. `font-lock-comment-face' Embedded comments
  843. ")
  844. ;;; Portability stuff:
  845. (defmacro cperl-define-key (emacs-key definition &optional xemacs-key)
  846. `(define-key cperl-mode-map
  847. ,(if xemacs-key
  848. `(if (featurep 'xemacs) ,xemacs-key ,emacs-key)
  849. emacs-key)
  850. ,definition))
  851. (defvar cperl-del-back-ch
  852. (car (append (where-is-internal 'delete-backward-char)
  853. (where-is-internal 'backward-delete-char-untabify)))
  854. "Character generated by key bound to `delete-backward-char'.")
  855. (and (vectorp cperl-del-back-ch) (= (length cperl-del-back-ch) 1)
  856. (setq cperl-del-back-ch (aref cperl-del-back-ch 0)))
  857. (defun cperl-mark-active () (mark)) ; Avoid undefined warning
  858. (if (featurep 'xemacs)
  859. (progn
  860. ;; "Active regions" are on: use region only if active
  861. ;; "Active regions" are off: use region unconditionally
  862. (defun cperl-use-region-p ()
  863. (if zmacs-regions (mark) t)))
  864. (defun cperl-use-region-p ()
  865. (if transient-mark-mode mark-active t))
  866. (defun cperl-mark-active () mark-active))
  867. (defsubst cperl-enable-font-lock ()
  868. cperl-can-font-lock)
  869. (defun cperl-putback-char (c) ; Emacs 19
  870. (push c unread-command-events)) ; Avoid undefined warning
  871. (if (featurep 'xemacs)
  872. (defun cperl-putback-char (c) ; XEmacs >= 19.12
  873. (push (eval '(character-to-event c)) unread-command-events)))
  874. (or (fboundp 'uncomment-region)
  875. (defun uncomment-region (beg end)
  876. (interactive "r")
  877. (comment-region beg end -1)))
  878. (defvar cperl-do-not-fontify
  879. (if (string< emacs-version "19.30")
  880. 'fontified
  881. 'lazy-lock)
  882. "Text property which inhibits refontification.")
  883. (defsubst cperl-put-do-not-fontify (from to &optional post)
  884. ;; If POST, do not do it with postponed fontification
  885. (if (and post cperl-syntaxify-by-font-lock)
  886. nil
  887. (put-text-property (max (point-min) (1- from))
  888. to cperl-do-not-fontify t)))
  889. (defcustom cperl-mode-hook nil
  890. "Hook run by CPerl mode."
  891. :type 'hook
  892. :group 'cperl)
  893. (defvar cperl-syntax-state nil)
  894. (defvar cperl-syntax-done-to nil)
  895. (defvar cperl-emacs-can-parse (> (length (save-excursion
  896. (parse-partial-sexp (point) (point)))) 9))
  897. ;; Make customization possible "in reverse"
  898. (defsubst cperl-val (symbol &optional default hairy)
  899. (cond
  900. ((eq (symbol-value symbol) 'null) default)
  901. (cperl-hairy (or hairy t))
  902. (t (symbol-value symbol))))
  903. (defun cperl-make-indent (column &optional minimum keep)
  904. "Makes indent of the current line the requested amount.
  905. Unless KEEP, removes the old indentation. Works around a bug in ancient
  906. versions of Emacs."
  907. (let ((prop (get-text-property (point) 'syntax-type)))
  908. (or keep
  909. (delete-horizontal-space))
  910. (indent-to column minimum)
  911. ;; In old versions (e.g., 19.33) `indent-to' would not inherit properties
  912. (and prop
  913. (> (current-column) 0)
  914. (save-excursion
  915. (beginning-of-line)
  916. (or (get-text-property (point) 'syntax-type)
  917. (and (looking-at "\\=[ \t]")
  918. (put-text-property (point) (match-end 0)
  919. 'syntax-type prop)))))))
  920. ;;; Probably it is too late to set these guys already, but it can help later:
  921. ;;;(and cperl-clobber-mode-lists
  922. ;;;(setq auto-mode-alist
  923. ;;; (append '(("\\.\\([pP][Llm]\\|al\\)$" . perl-mode)) auto-mode-alist ))
  924. ;;;(and (boundp 'interpreter-mode-alist)
  925. ;;; (setq interpreter-mode-alist (append interpreter-mode-alist
  926. ;;; '(("miniperl" . perl-mode))))))
  927. (eval-when-compile
  928. (mapc (lambda (p)
  929. (condition-case nil
  930. (require p)
  931. (error nil)))
  932. '(imenu easymenu etags timer man info))
  933. (if (fboundp 'ps-extend-face-list)
  934. (defmacro cperl-ps-extend-face-list (arg)
  935. `(ps-extend-face-list ,arg))
  936. (defmacro cperl-ps-extend-face-list (arg)
  937. `(error "This version of Emacs has no `ps-extend-face-list'")))
  938. ;; Calling `cperl-enable-font-lock' below doesn't compile on XEmacs,
  939. ;; macros instead of defsubsts don't work on Emacs, so we do the
  940. ;; expansion manually. Any other suggestions?
  941. (require 'cl))
  942. (defvar cperl-mode-abbrev-table nil
  943. "Abbrev table in use in CPerl mode buffers.")
  944. (add-hook 'edit-var-mode-alist '(perl-mode (regexp . "^cperl-")))
  945. (defvar cperl-mode-map () "Keymap used in CPerl mode.")
  946. (if cperl-mode-map nil
  947. (setq cperl-mode-map (make-sparse-keymap))
  948. (cperl-define-key "{" 'cperl-electric-lbrace)
  949. (cperl-define-key "[" 'cperl-electric-paren)
  950. (cperl-define-key "(" 'cperl-electric-paren)
  951. (cperl-define-key "<" 'cperl-electric-paren)
  952. (cperl-define-key "}" 'cperl-electric-brace)
  953. (cperl-define-key "]" 'cperl-electric-rparen)
  954. (cperl-define-key ")" 'cperl-electric-rparen)
  955. (cperl-define-key ";" 'cperl-electric-semi)
  956. (cperl-define-key ":" 'cperl-electric-terminator)
  957. (cperl-define-key "\C-j" 'newline-and-indent)
  958. (cperl-define-key "\C-c\C-j" 'cperl-linefeed)
  959. (cperl-define-key "\C-c\C-t" 'cperl-invert-if-unless)
  960. (cperl-define-key "\C-c\C-a" 'cperl-toggle-auto-newline)
  961. (cperl-define-key "\C-c\C-k" 'cperl-toggle-abbrev)
  962. (cperl-define-key "\C-c\C-w" 'cperl-toggle-construct-fix)
  963. (cperl-define-key "\C-c\C-f" 'auto-fill-mode)
  964. (cperl-define-key "\C-c\C-e" 'cperl-toggle-electric)
  965. (cperl-define-key "\C-c\C-b" 'cperl-find-bad-style)
  966. (cperl-define-key "\C-c\C-p" 'cperl-pod-spell)
  967. (cperl-define-key "\C-c\C-d" 'cperl-here-doc-spell)
  968. (cperl-define-key "\C-c\C-n" 'cperl-narrow-to-here-doc)
  969. (cperl-define-key "\C-c\C-v" 'cperl-next-interpolated-REx)
  970. (cperl-define-key "\C-c\C-x" 'cperl-next-interpolated-REx-0)
  971. (cperl-define-key "\C-c\C-y" 'cperl-next-interpolated-REx-1)
  972. (cperl-define-key "\C-c\C-ha" 'cperl-toggle-autohelp)
  973. (cperl-define-key "\C-c\C-hp" 'cperl-perldoc)
  974. (cperl-define-key "\C-c\C-hP" 'cperl-perldoc-at-point)
  975. (cperl-define-key "\e\C-q" 'cperl-indent-exp) ; Usually not bound
  976. (cperl-define-key [?\C-\M-\|] 'cperl-lineup
  977. [(control meta |)])
  978. ;;(cperl-define-key "\M-q" 'cperl-fill-paragraph)
  979. ;;(cperl-define-key "\e;" 'cperl-indent-for-comment)
  980. (cperl-define-key "\177" 'cperl-electric-backspace)
  981. (cperl-define-key "\t" 'cperl-indent-command)
  982. ;; don't clobber the backspace binding:
  983. (cperl-define-key "\C-c\C-hF" 'cperl-info-on-command
  984. [(control c) (control h) F])
  985. (if (cperl-val 'cperl-clobber-lisp-bindings)
  986. (progn
  987. (cperl-define-key "\C-hf"
  988. ;;(concat (char-to-string help-char) "f") ; does not work
  989. 'cperl-info-on-command
  990. [(control h) f])
  991. (cperl-define-key "\C-hv"
  992. ;;(concat (char-to-string help-char) "v") ; does not work
  993. 'cperl-get-help
  994. [(control h) v])
  995. (cperl-define-key "\C-c\C-hf"
  996. ;;(concat (char-to-string help-char) "f") ; does not work
  997. (key-binding "\C-hf")
  998. [(control c) (control h) f])
  999. (cperl-define-key "\C-c\C-hv"
  1000. ;;(concat (char-to-string help-char) "v") ; does not work
  1001. (key-binding "\C-hv")
  1002. [(control c) (control h) v]))
  1003. (cperl-define-key "\C-c\C-hf" 'cperl-info-on-current-command
  1004. [(control c) (control h) f])
  1005. (cperl-define-key "\C-c\C-hv"
  1006. ;;(concat (char-to-string help-char) "v") ; does not work
  1007. 'cperl-get-help
  1008. [(control c) (control h) v]))
  1009. (if (and (featurep 'xemacs)
  1010. (<= emacs-minor-version 11) (<= emacs-major-version 19))
  1011. (progn
  1012. ;; substitute-key-definition is usefulness-deenhanced...
  1013. ;;;;;(cperl-define-key "\M-q" 'cperl-fill-paragraph)
  1014. (cperl-define-key "\e;" 'cperl-indent-for-comment)
  1015. (cperl-define-key "\e\C-\\" 'cperl-indent-region))
  1016. (or (boundp 'fill-paragraph-function)
  1017. (substitute-key-definition
  1018. 'fill-paragraph 'cperl-fill-paragraph
  1019. cperl-mode-map global-map))
  1020. (substitute-key-definition
  1021. 'indent-sexp 'cperl-indent-exp
  1022. cperl-mode-map global-map)
  1023. (substitute-key-definition
  1024. 'indent-region 'cperl-indent-region
  1025. cperl-mode-map global-map)
  1026. (substitute-key-definition
  1027. 'indent-for-comment 'cperl-indent-for-comment
  1028. cperl-mode-map global-map)))
  1029. (defvar cperl-menu)
  1030. (defvar cperl-lazy-installed)
  1031. (defvar cperl-old-style nil)
  1032. (condition-case nil
  1033. (progn
  1034. (require 'easymenu)
  1035. (easy-menu-define
  1036. cperl-menu cperl-mode-map "Menu for CPerl mode"
  1037. '("Perl"
  1038. ["Beginning of function" beginning-of-defun t]
  1039. ["End of function" end-of-defun t]
  1040. ["Mark function" mark-defun t]
  1041. ["Indent expression" cperl-indent-exp t]
  1042. ["Fill paragraph/comment" fill-paragraph t]
  1043. "----"
  1044. ["Line up a construction" cperl-lineup (cperl-use-region-p)]
  1045. ["Invert if/unless/while etc" cperl-invert-if-unless t]
  1046. ("Regexp"
  1047. ["Beautify" cperl-beautify-regexp
  1048. cperl-use-syntax-table-text-property]
  1049. ["Beautify one level deep" (cperl-beautify-regexp 1)
  1050. cperl-use-syntax-table-text-property]
  1051. ["Beautify a group" cperl-beautify-level
  1052. cperl-use-syntax-table-text-property]
  1053. ["Beautify a group one level deep" (cperl-beautify-level 1)
  1054. cperl-use-syntax-table-text-property]
  1055. ["Contract a group" cperl-contract-level
  1056. cperl-use-syntax-table-text-property]
  1057. ["Contract groups" cperl-contract-levels
  1058. cperl-use-syntax-table-text-property]
  1059. "----"
  1060. ["Find next interpolated" cperl-next-interpolated-REx
  1061. (next-single-property-change (point-min) 'REx-interpolated)]
  1062. ["Find next interpolated (no //o)"
  1063. cperl-next-interpolated-REx-0
  1064. (or (text-property-any (point-min) (point-max) 'REx-interpolated t)
  1065. (text-property-any (point-min) (point-max) 'REx-interpolated 1))]
  1066. ["Find next interpolated (neither //o nor whole-REx)"
  1067. cperl-next-interpolated-REx-1
  1068. (text-property-any (point-min) (point-max) 'REx-interpolated t)])
  1069. ["Insert spaces if needed to fix style" cperl-find-bad-style t]
  1070. ["Refresh \"hard\" constructions" cperl-find-pods-heres t]
  1071. "----"
  1072. ["Indent region" cperl-indent-region (cperl-use-region-p)]
  1073. ["Comment region" cperl-comment-region (cperl-use-region-p)]
  1074. ["Uncomment region" cperl-uncomment-region (cperl-use-region-p)]
  1075. "----"
  1076. ["Run" mode-compile (fboundp 'mode-compile)]
  1077. ["Kill" mode-compile-kill (and (fboundp 'mode-compile-kill)
  1078. (get-buffer "*compilation*"))]
  1079. ["Next error" next-error (get-buffer "*compilation*")]
  1080. ["Check syntax" cperl-check-syntax (fboundp 'mode-compile)]
  1081. "----"
  1082. ["Debugger" cperl-db t]
  1083. "----"
  1084. ("Tools"
  1085. ["Imenu" imenu (fboundp 'imenu)]
  1086. ["Imenu on Perl Info" cperl-imenu-on-info (featurep 'imenu)]
  1087. "----"
  1088. ["Ispell PODs" cperl-pod-spell
  1089. ;; Better not to update syntaxification here:
  1090. ;; debugging syntaxification can be broken by this???
  1091. (or
  1092. (get-text-property (point-min) 'in-pod)
  1093. (< (progn
  1094. (and cperl-syntaxify-for-menu
  1095. (cperl-update-syntaxification (point-max) (point-max)))
  1096. (next-single-property-change (point-min) 'in-pod nil (point-max)))
  1097. (point-max)))]
  1098. ["Ispell HERE-DOCs" cperl-here-doc-spell
  1099. (< (progn
  1100. (and cperl-syntaxify-for-menu
  1101. (cperl-update-syntaxification (point-max) (point-max)))
  1102. (next-single-property-change (point-min) 'here-doc-group nil (point-max)))
  1103. (point-max))]
  1104. ["Narrow to this HERE-DOC" cperl-narrow-to-here-doc
  1105. (eq 'here-doc (progn
  1106. (and cperl-syntaxify-for-menu
  1107. (cperl-update-syntaxification (point) (point)))
  1108. (get-text-property (point) 'syntax-type)))]
  1109. ["Select this HERE-DOC or POD section"
  1110. cperl-select-this-pod-or-here-doc
  1111. (memq (progn
  1112. (and cperl-syntaxify-for-menu
  1113. (cperl-update-syntaxification (point) (point)))
  1114. (get-text-property (point) 'syntax-type))
  1115. '(here-doc pod))]
  1116. "----"
  1117. ["CPerl pretty print (experimental)" cperl-ps-print
  1118. (fboundp 'ps-extend-face-list)]
  1119. "----"
  1120. ["Syntaxify region" cperl-find-pods-heres-region
  1121. (cperl-use-region-p)]
  1122. ["Profile syntaxification" cperl-time-fontification t]
  1123. ["Debug errors in delayed fontification" cperl-emulate-lazy-lock t]
  1124. ["Debug unwind for syntactic scan" cperl-toggle-set-debug-unwind t]
  1125. ["Debug backtrace on syntactic scan (BEWARE!!!)"
  1126. (cperl-toggle-set-debug-unwind nil t) t]
  1127. "----"
  1128. ["Class Hierarchy from TAGS" cperl-tags-hier-init t]
  1129. ;;["Update classes" (cperl-tags-hier-init t) tags-table-list]
  1130. ("Tags"
  1131. ;;; ["Create tags for current file" cperl-etags t]
  1132. ;;; ["Add tags for current file" (cperl-etags t) t]
  1133. ;;; ["Create tags for Perl files in directory" (cperl-etags nil t) t]
  1134. ;;; ["Add tags for Perl files in directory" (cperl-etags t t) t]
  1135. ;;; ["Create tags for Perl files in (sub)directories"
  1136. ;;; (cperl-etags nil 'recursive) t]
  1137. ;;; ["Add tags for Perl files in (sub)directories"
  1138. ;;; (cperl-etags t 'recursive) t])
  1139. ;;;; cperl-write-tags (&optional file erase recurse dir inbuffer)
  1140. ["Create tags for current file" (cperl-write-tags nil t) t]
  1141. ["Add tags for current file" (cperl-write-tags) t]
  1142. ["Create tags for Perl files in directory"
  1143. (cperl-write-tags nil t nil t) t]
  1144. ["Add tags for Perl files in directory"
  1145. (cperl-write-tags nil nil nil t) t]
  1146. ["Create tags for Perl files in (sub)directories"
  1147. (cperl-write-tags nil t t t) t]
  1148. ["Add tags for Perl files in (sub)directories"
  1149. (cperl-write-tags nil nil t t) t]))
  1150. ("Perl docs"
  1151. ["Define word at point" imenu-go-find-at-position
  1152. (fboundp 'imenu-go-find-at-position)]
  1153. ["Help on function" cperl-info-on-command t]
  1154. ["Help on function at point" cperl-info-on-current-command t]
  1155. ["Help on symbol at point" cperl-get-help t]
  1156. ["Perldoc" cperl-perldoc t]
  1157. ["Perldoc on word at point" cperl-perldoc-at-point t]
  1158. ["View manpage of POD in this file" cperl-build-manpage t]
  1159. ["Auto-help on" cperl-lazy-install
  1160. (and (fboundp 'run-with-idle-timer)
  1161. (not cperl-lazy-installed))]
  1162. ["Auto-help off" cperl-lazy-unstall
  1163. (and (fboundp 'run-with-idle-timer)
  1164. cperl-lazy-installed)])
  1165. ("Toggle..."
  1166. ["Auto newline" cperl-toggle-auto-newline t]
  1167. ["Electric parens" cperl-toggle-electric t]
  1168. ["Electric keywords" cperl-toggle-abbrev t]
  1169. ["Fix whitespace on indent" cperl-toggle-construct-fix t]
  1170. ["Auto-help on Perl constructs" cperl-toggle-autohelp t]
  1171. ["Auto fill" auto-fill-mode t])
  1172. ("Indent styles..."
  1173. ["CPerl" (cperl-set-style "CPerl") t]
  1174. ["PerlStyle" (cperl-set-style "PerlStyle") t]
  1175. ["GNU" (cperl-set-style "GNU") t]
  1176. ["C++" (cperl-set-style "C++") t]
  1177. ["K&R" (cperl-set-style "K&R") t]
  1178. ["BSD" (cperl-set-style "BSD") t]
  1179. ["Whitesmith" (cperl-set-style "Whitesmith") t]
  1180. ["Memorize Current" (cperl-set-style "Current") t]
  1181. ["Memorized" (cperl-set-style-back) cperl-old-style])
  1182. ("Micro-docs"
  1183. ["Tips" (describe-variable 'cperl-tips) t]
  1184. ["Problems" (describe-variable 'cperl-problems) t]
  1185. ["Speed" (describe-variable 'cperl-speed) t]
  1186. ["Praise" (describe-variable 'cperl-praise) t]
  1187. ["Faces" (describe-variable 'cperl-tips-faces) t]
  1188. ["CPerl mode" (describe-function 'cperl-mode) t]
  1189. ["CPerl version"
  1190. (message "The version of master-file for this CPerl is %s-Emacs"
  1191. cperl-version) t]))))
  1192. (error nil))
  1193. (autoload 'c-macro-expand "cmacexp"
  1194. "Display the result of expanding all C macros occurring in the region.
  1195. The expansion is entirely correct because it uses the C preprocessor."
  1196. t)
  1197. ;;; These two must be unwound, otherwise take exponential time
  1198. (defconst cperl-maybe-white-and-comment-rex "[ \t\n]*\\(#[^\n]*\n[ \t\n]*\\)*"
  1199. "Regular expression to match optional whitespace with interspersed comments.
  1200. Should contain exactly one group.")
  1201. ;;; This one is tricky to unwind; still very inefficient...
  1202. (defconst cperl-white-and-comment-rex "\\([ \t\n]\\|#[^\n]*\n\\)+"
  1203. "Regular expression to match whitespace with interspersed comments.
  1204. Should contain exactly one group.")
  1205. ;;; Is incorporated in `cperl-imenu--function-name-regexp-perl'
  1206. ;;; `cperl-outline-regexp', `defun-prompt-regexp'.
  1207. ;;; Details of groups in this may be used in several functions; see comments
  1208. ;;; near mentioned above variable(s)...
  1209. ;;; sub($$):lvalue{} sub:lvalue{} Both allowed...
  1210. (defsubst cperl-after-sub-regexp (named attr) ; 9 groups without attr...
  1211. "Match the text after `sub' in a subroutine declaration.
  1212. If NAMED is nil, allows anonymous subroutines. Matches up to the first \":\"
  1213. of attributes (if present), or end of the name or prototype (whatever is
  1214. the last)."
  1215. (concat ; Assume n groups before this...
  1216. "\\(" ; n+1=name-group
  1217. cperl-white-and-comment-rex ; n+2=pre-name
  1218. "\\(::[a-zA-Z_0-9:']+\\|[a-zA-Z_'][a-zA-Z_0-9:']*\\)" ; n+3=name
  1219. "\\)" ; END n+1=name-group
  1220. (if named "" "?")
  1221. "\\(" ; n+4=proto-group
  1222. cperl-maybe-white-and-comment-rex ; n+5=pre-proto
  1223. "\\(([^()]*)\\)" ; n+6=prototype
  1224. "\\)?" ; END n+4=proto-group
  1225. "\\(" ; n+7=attr-group
  1226. cperl-maybe-white-and-comment-rex ; n+8=pre-attr
  1227. "\\(" ; n+9=start-attr
  1228. ":"
  1229. (if attr (concat
  1230. "\\("
  1231. cperl-maybe-white-and-comment-rex ; whitespace-comments
  1232. "\\(\\sw\\|_\\)+" ; attr-name
  1233. ;; attr-arg (1 level of internal parens allowed!)
  1234. "\\((\\(\\\\.\\|[^\\\\()]\\|([^\\\\()]*)\\)*)\\)?"
  1235. "\\(" ; optional : (XXX allows trailing???)
  1236. cperl-maybe-white-and-comment-rex ; whitespace-comments
  1237. ":\\)?"
  1238. "\\)+")
  1239. "[^:]")
  1240. "\\)"
  1241. "\\)?" ; END n+6=proto-group
  1242. ))
  1243. ;;; Details of groups in this are used in `cperl-imenu--create-perl-index'
  1244. ;;; and `cperl-outline-level'.
  1245. ;;;; Was: 2=sub|package; now 2=package-group, 5=package-name 8=sub-name (+3)
  1246. (defvar cperl-imenu--function-name-regexp-perl
  1247. (concat
  1248. "^\\(" ; 1 = all
  1249. "\\([ \t]*package" ; 2 = package-group
  1250. "\\(" ; 3 = package-name-group
  1251. cperl-white-and-comment-rex ; 4 = pre-package-name
  1252. "\\([a-zA-Z_0-9:']+\\)\\)?\\)" ; 5 = package-name
  1253. "\\|"
  1254. "[ \t]*sub"
  1255. (cperl-after-sub-regexp 'named nil) ; 8=name 11=proto 14=attr-start
  1256. cperl-maybe-white-and-comment-rex ; 15=pre-block
  1257. "\\|"
  1258. "=head\\([1-4]\\)[ \t]+" ; 16=level
  1259. "\\([^\n]+\\)$" ; 17=text
  1260. "\\)"))
  1261. (defvar cperl-outline-regexp
  1262. (concat cperl-imenu--function-name-regexp-perl "\\|" "\\`"))
  1263. (defvar cperl-mode-syntax-table nil
  1264. "Syntax table in use in CPerl mode buffers.")
  1265. (defvar cperl-string-syntax-table nil
  1266. "Syntax table in use in CPerl mode string-like chunks.")
  1267. (defsubst cperl-1- (p)
  1268. (max (point-min) (1- p)))
  1269. (defsubst cperl-1+ (p)
  1270. (min (point-max) (1+ p)))
  1271. (if cperl-mode-syntax-table
  1272. ()
  1273. (setq cperl-mode-syntax-table (make-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 ?$ "\\" cperl-mode-syntax-table)
  1285. (modify-syntax-entry ?\n ">" cperl-mode-syntax-table)
  1286. (modify-syntax-entry ?# "<" cperl-mode-syntax-table)
  1287. (modify-syntax-entry ?' "\"" cperl-mode-syntax-table)
  1288. (modify-syntax-entry ?` "\"" cperl-mode-syntax-table)
  1289. (if cperl-under-as-char
  1290. (modify-syntax-entry ?_ "w" cperl-mode-syntax-table))
  1291. (modify-syntax-entry ?: "_" cperl-mode-syntax-table)
  1292. (modify-syntax-entry ?| "." cperl-mode-syntax-table)
  1293. (setq cperl-string-syntax-table (copy-syntax-table cperl-mode-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)
  1300. (modify-syntax-entry ?# "." cperl-string-syntax-table)) ; (?# comment )
  1301. (defvar cperl-faces-init nil)
  1302. ;; Fix for msb.el
  1303. (defvar cperl-msb-fixed nil)
  1304. (defvar cperl-use-major-mode 'cperl-mode)
  1305. (defvar cperl-font-lock-multiline-start nil)
  1306. (defvar cperl-font-lock-multiline nil)
  1307. (defvar cperl-font-locking nil)
  1308. ;; NB as it stands the code in cperl-mode assumes this only has one
  1309. ;; element. If XEmacs 19 support were dropped, this could all be simplified.
  1310. (defvar cperl-compilation-error-regexp-alist
  1311. ;; This look like a paranoiac regexp: could anybody find a better one? (which WORKS).
  1312. '(("^[^\n]* \\(file\\|at\\) \\([^ \t\n]+\\) [^\n]*line \\([0-9]+\\)[\\., \n]"
  1313. 2 3))
  1314. "Alist that specifies how to match errors in perl output.")
  1315. (defvar compilation-error-regexp-alist)
  1316. ;;;###autoload
  1317. (define-derived-mode cperl-mode prog-mode "CPerl"
  1318. "Major mode for editing Perl code.
  1319. Expression and list commands understand all C brackets.
  1320. Tab indents for Perl code.
  1321. Paragraphs are separated by blank lines only.
  1322. Delete converts tabs to spaces as it moves back.
  1323. Various characters in Perl almost always come in pairs: {}, (), [],
  1324. sometimes <>. When the user types the first, she gets the second as
  1325. well, with optional special formatting done on {}. (Disabled by
  1326. default.) You can always quote (with \\[quoted-insert]) the left
  1327. \"paren\" to avoid the expansion. The processing of < is special,
  1328. since most the time you mean \"less\". CPerl mode tries to guess
  1329. whether you want to type pair <>, and inserts is if it
  1330. appropriate. You can set `cperl-electric-parens-string' to the string that
  1331. contains the parens from the above list you want to be electrical.
  1332. Electricity of parens is controlled by `cperl-electric-parens'.
  1333. You may also set `cperl-electric-parens-mark' to have electric parens
  1334. look for active mark and \"embrace\" a region if possible.'
  1335. CPerl mode provides expansion of the Perl control constructs:
  1336. if, else, elsif, unless, while, until, continue, do,
  1337. for, foreach, formy and foreachmy.
  1338. and POD directives (Disabled by default, see `cperl-electric-keywords'.)
  1339. The user types the keyword immediately followed by a space, which
  1340. causes the construct to be expanded, and the point is positioned where
  1341. she is most likely to want to be. E.g., when the user types a space
  1342. following \"if\" the following appears in the buffer: if () { or if ()
  1343. } { } and the cursor is between the parentheses. The user can then
  1344. type some boolean expression within the parens. Having done that,
  1345. typing \\[cperl-linefeed] places you - appropriately indented - on a
  1346. new line between the braces (if you typed \\[cperl-linefeed] in a POD
  1347. directive line, then appropriate number of new lines is inserted).
  1348. If CPerl decides that you want to insert \"English\" style construct like
  1349. bite if angry;
  1350. it will not do any expansion. See also help on variable
  1351. `cperl-extra-newline-before-brace'. (Note that one can switch the
  1352. help message on expansion by setting `cperl-message-electric-keyword'
  1353. to nil.)
  1354. \\[cperl-linefeed] is a convenience replacement for typing carriage
  1355. return. It places you in the next line with proper indentation, or if
  1356. you type it inside the inline block of control construct, like
  1357. foreach (@lines) {print; print}
  1358. and you are on a boundary of a statement inside braces, it will
  1359. transform the construct into a multiline and will place you into an
  1360. appropriately indented blank line. If you need a usual
  1361. `newline-and-indent' behavior, it is on \\[newline-and-indent],
  1362. see documentation on `cperl-electric-linefeed'.
  1363. Use \\[cperl-invert-if-unless] to change a construction of the form
  1364. if (A) { B }
  1365. into
  1366. B if A;
  1367. \\{cperl-mode-map}
  1368. Setting the variable `cperl-font-lock' to t switches on font-lock-mode
  1369. \(even with older Emacsen), `cperl-electric-lbrace-space' to t switches
  1370. on electric space between $ and {, `cperl-electric-parens-string' is
  1371. the string that contains parentheses that should be electric in CPerl
  1372. \(see also `cperl-electric-parens-mark' and `cperl-electric-parens'),
  1373. setting `cperl-electric-keywords' enables electric expansion of
  1374. control structures in CPerl. `cperl-electric-linefeed' governs which
  1375. one of two linefeed behavior is preferable. You can enable all these
  1376. options simultaneously (recommended mode of use) by setting
  1377. `cperl-hairy' to t. In this case you can switch separate options off
  1378. by setting them to `null'. Note that one may undo the extra
  1379. whitespace inserted by semis and braces in `auto-newline'-mode by
  1380. consequent \\[cperl-electric-backspace].
  1381. If your site has perl5 documentation in info format, you can use commands
  1382. \\[cperl-info-on-current-command] and \\[cperl-info-on-command] to access it.
  1383. These keys run commands `cperl-info-on-current-command' and
  1384. `cperl-info-on-command', which one is which is controlled by variable
  1385. `cperl-info-on-command-no-prompt' and `cperl-clobber-lisp-bindings'
  1386. \(in turn affected by `cperl-hairy').
  1387. Even if you have no info-format documentation, short one-liner-style
  1388. help is available on \\[cperl-get-help], and one can run perldoc or
  1389. man via menu.
  1390. It is possible to show this help automatically after some idle time.
  1391. This is regulated by variable `cperl-lazy-help-time'. Default with
  1392. `cperl-hairy' (if the value of `cperl-lazy-help-time' is nil) is 5
  1393. secs idle time . It is also possible to switch this on/off from the
  1394. menu, or via \\[cperl-toggle-autohelp]. Requires `run-with-idle-timer'.
  1395. Use \\[cperl-lineup] to vertically lineup some construction - put the
  1396. beginning of the region at the start of construction, and make region
  1397. span the needed amount of lines.
  1398. Variables `cperl-pod-here-scan', `cperl-pod-here-fontify',
  1399. `cperl-pod-face', `cperl-pod-head-face' control processing of POD and
  1400. here-docs sections. With capable Emaxen results of scan are used
  1401. for indentation too, otherwise they are used for highlighting only.
  1402. Variables controlling indentation style:
  1403. `cperl-tab-always-indent'
  1404. Non-nil means TAB in CPerl mode should always reindent the current line,
  1405. regardless of where in the line point is when the TAB command is used.
  1406. `cperl-indent-left-aligned-comments'
  1407. Non-nil means that the comment starting in leftmost column should indent.
  1408. `cperl-auto-newline'
  1409. Non-nil means automatically newline before and after braces,
  1410. and after colons and semicolons, inserted in Perl code. The following
  1411. \\[cperl-electric-backspace] will remove the inserted whitespace.
  1412. Insertion after colons requires both this variable and
  1413. `cperl-auto-newline-after-colon' set.
  1414. `cperl-auto-newline-after-colon'
  1415. Non-nil means automatically newline even after colons.
  1416. Subject to `cperl-auto-newline' setting.
  1417. `cperl-indent-level'
  1418. Indentation of Perl statements within surrounding block.
  1419. The surrounding block's indentation is the indentation
  1420. of the line on which the open-brace appears.
  1421. `cperl-continued-statement-offset'
  1422. Extra indentation given to a substatement, such as the
  1423. then-clause of an if, or body of a while, or just a statement continuation.
  1424. `cperl-continued-brace-offset'
  1425. Extra indentation given to a brace that starts a substatement.
  1426. This is in addition to `cperl-continued-statement-offset'.
  1427. `cperl-brace-offset'
  1428. Extra indentation for line if it starts with an open brace.
  1429. `cperl-brace-imaginary-offset'
  1430. An open brace following other text is treated as if it the line started
  1431. this far to the right of the actual line indentation.
  1432. `cperl-label-offset'
  1433. Extra indentation for line that is a label.
  1434. `cperl-min-label-indent'
  1435. Minimal indentation for line that is a label.
  1436. Settings for classic indent-styles: K&R BSD=C++ GNU PerlStyle=Whitesmith
  1437. `cperl-indent-level' 5 4 2 4
  1438. `cperl-brace-offset' 0 0 0 0
  1439. `cperl-continued-brace-offset' -5 -4 0 0
  1440. `cperl-label-offset' -5 -4 -2 -4
  1441. `cperl-continued-statement-offset' 5 4 2 4
  1442. CPerl knows several indentation styles, and may bulk set the
  1443. corresponding variables. Use \\[cperl-set-style] to do this. Use
  1444. \\[cperl-set-style-back] to restore the memorized preexisting values
  1445. \(both available from menu). See examples in `cperl-style-examples'.
  1446. Part of the indentation style is how different parts of if/elsif/else
  1447. statements are broken into lines; in CPerl, this is reflected on how
  1448. templates for these constructs are created (controlled by
  1449. `cperl-extra-newline-before-brace'), and how reflow-logic should treat
  1450. \"continuation\" blocks of else/elsif/continue, controlled by the same
  1451. variable, and by `cperl-extra-newline-before-brace-multiline',
  1452. `cperl-merge-trailing-else', `cperl-indent-region-fix-constructs'.
  1453. If `cperl-indent-level' is 0, the statement after opening brace in
  1454. column 0 is indented on
  1455. `cperl-brace-offset'+`cperl-continued-statement-offset'.
  1456. Turning on CPerl mode calls the hooks in the variable `cperl-mode-hook'
  1457. with no args.
  1458. DO NOT FORGET to read micro-docs (available from `Perl' menu)
  1459. or as help on variables `cperl-tips', `cperl-problems',
  1460. `cperl-praise', `cperl-speed'."
  1461. (if (cperl-val 'cperl-electric-linefeed)
  1462. (progn
  1463. (local-set-key "\C-J" 'cperl-linefeed)
  1464. (local-set-key "\C-C\C-J" 'newline-and-indent)))
  1465. (if (and
  1466. (cperl-val 'cperl-clobber-lisp-bindings)
  1467. (cperl-val 'cperl-info-on-command-no-prompt))
  1468. (progn
  1469. ;; don't clobber the backspace binding:
  1470. (cperl-define-key "\C-hf" 'cperl-info-on-current-command [(control h) f])
  1471. (cperl-define-key "\C-c\C-hf" 'cperl-info-on-command
  1472. [(control c) (control h) f])))
  1473. (let ((prev-a-c abbrevs-changed))
  1474. (define-abbrev-table 'cperl-mode-abbrev-table '(
  1475. ("if" "if" cperl-electric-keyword 0)
  1476. ("elsif" "elsif" cperl-electric-keyword 0)
  1477. ("while" "while" cperl-electric-keyword 0)
  1478. ("until" "until" cperl-electric-keyword 0)
  1479. ("unless" "unless" cperl-electric-keyword 0)
  1480. ("else" "else" cperl-electric-else 0)
  1481. ("continue" "continue" cperl-electric-else 0)
  1482. ("for" "for" cperl-electric-keyword 0)
  1483. ("foreach" "foreach" cperl-electric-keyword 0)
  1484. ("formy" "formy" cperl-electric-keyword 0)
  1485. ("foreachmy" "foreachmy" cperl-electric-keyword 0)
  1486. ("do" "do" cperl-electric-keyword 0)
  1487. ("=pod" "=pod" cperl-electric-pod 0)
  1488. ("=over" "=over" cperl-electric-pod 0)
  1489. ("=head1" "=head1" cperl-electric-pod 0)
  1490. ("=head2" "=head2" cperl-electric-pod 0)
  1491. ("pod" "pod" cperl-electric-pod 0)
  1492. ("over" "over" cperl-electric-pod 0)
  1493. ("head1" "head1" cperl-electric-pod 0)
  1494. ("head2" "head2" cperl-electric-pod 0)))
  1495. (setq abbrevs-changed prev-a-c))
  1496. (setq local-abbrev-table cperl-mode-abbrev-table)
  1497. (if (cperl-val 'cperl-electric-keywords)
  1498. (abbrev-mode 1))
  1499. (set-syntax-table cperl-mode-syntax-table)
  1500. ;; Until Emacs is multi-threaded, we do not actually need it local:
  1501. (make-local-variable 'cperl-font-lock-multiline-start)
  1502. (make-local-variable 'cperl-font-locking)
  1503. (make-local-variable 'outline-regexp)
  1504. ;; (setq outline-regexp imenu-example--function-name-regexp-perl)
  1505. (setq outline-regexp cperl-outline-regexp)
  1506. (make-local-variable 'outline-level)
  1507. (setq outline-level 'cperl-outline-level)
  1508. (make-local-variable 'add-log-current-defun-function)
  1509. (setq add-log-current-defun-function
  1510. (lambda ()
  1511. (save-excursion
  1512. (if (re-search-backward "^sub[ \t]+\\([^({ \t\n]+\\)" nil t)
  1513. (match-string-no-properties 1)))))
  1514. (make-local-variable 'paragraph-start)
  1515. (setq paragraph-start (concat "^$\\|" page-delimiter))
  1516. (make-local-variable 'paragraph-separate)
  1517. (setq paragraph-separate paragraph-start)
  1518. (make-local-variable 'paragraph-ignore-fill-prefix)
  1519. (setq paragraph-ignore-fill-prefix t)
  1520. (if (featurep 'xemacs)
  1521. (progn
  1522. (make-local-variable 'paren-backwards-message)
  1523. (set 'paren-backwards-message t)))
  1524. (make-local-variable 'indent-line-function)
  1525. (setq indent-line-function 'cperl-indent-line)
  1526. (make-local-variable 'require-final-newline)
  1527. (setq require-final-newline mode-require-final-newline)
  1528. (make-local-variable 'comment-start)
  1529. (setq comment-start "# ")
  1530. (make-local-variable 'comment-end)
  1531. (setq comment-end "")
  1532. (make-local-variable 'comment-column)
  1533. (setq comment-column cperl-comment-column)
  1534. (make-local-variable 'comment-start-skip)
  1535. (setq comment-start-skip "#+ *")
  1536. (make-local-variable 'defun-prompt-regexp)
  1537. ;;; "[ \t]*sub"
  1538. ;;; (cperl-after-sub-regexp 'named nil) ; 8=name 11=proto 14=attr-start
  1539. ;;; cperl-maybe-white-and-comment-rex ; 15=pre-block
  1540. (setq defun-prompt-regexp
  1541. (concat "^[ \t]*\\(sub"
  1542. (cperl-after-sub-regexp 'named 'attr-groups)
  1543. "\\|" ; per toke.c
  1544. "\\(BEGIN\\|CHECK\\|INIT\\|END\\|AUTOLOAD\\|DESTROY\\)"
  1545. "\\)"
  1546. cperl-maybe-white-and-comment-rex))
  1547. (make-local-variable 'comment-indent-function)
  1548. (setq comment-indent-function 'cperl-comment-indent)
  1549. (and (boundp 'fill-paragraph-function)
  1550. (progn
  1551. (make-local-variable 'fill-paragraph-function)
  1552. (set 'fill-paragraph-function 'cperl-fill-paragraph)))
  1553. (make-local-variable 'parse-sexp-ignore-comments)
  1554. (setq parse-sexp-ignore-comments t)
  1555. (make-local-variable 'indent-region-function)
  1556. (setq indent-region-function 'cperl-indent-region)
  1557. ;;(setq auto-fill-function 'cperl-do-auto-fill) ; Need to switch on and off!
  1558. (make-local-variable 'imenu-create-index-function)
  1559. (setq imenu-create-index-function
  1560. (function cperl-imenu--create-perl-index))
  1561. (make-local-variable 'imenu-sort-function)
  1562. (setq imenu-sort-function nil)
  1563. (make-local-variable 'vc-rcs-header)
  1564. (set 'vc-rcs-header cperl-vc-rcs-header)
  1565. (make-local-variable 'vc-sccs-header)
  1566. (set 'vc-sccs-header cperl-vc-sccs-header)
  1567. (when (featurep 'xemacs)
  1568. ;; This one is obsolete...
  1569. (make-local-variable 'vc-header-alist)
  1570. (set 'vc-header-alist (or cperl-vc-header-alist ; Avoid warning
  1571. `((SCCS ,(car cperl-vc-sccs-header))
  1572. (RCS ,(car cperl-vc-rcs-header))))))
  1573. (cond ((boundp 'compilation-error-regexp-alist-alist);; xemacs 20.x
  1574. (make-local-variable 'compilation-error-regexp-alist-alist)
  1575. (set 'compilation-error-regexp-alist-alist
  1576. (cons (cons 'cperl (car cperl-compilation-error-regexp-alist))
  1577. (symbol-value 'compilation-error-regexp-alist-alist)))
  1578. (if (fboundp 'compilation-build-compilation-error-regexp-alist)
  1579. (let ((f 'compilation-build-compilation-error-regexp-alist))
  1580. (funcall f))
  1581. (make-local-variable 'compilation-error-regexp-alist)
  1582. (push 'cperl compilation-error-regexp-alist)))
  1583. ((boundp 'compilation-error-regexp-alist);; xemacs 19.x
  1584. (make-local-variable 'compilation-error-regexp-alist)
  1585. (set 'compilation-error-regexp-alist
  1586. (append cperl-compilation-error-regexp-alist
  1587. (symbol-value 'compilation-error-regexp-alist)))))
  1588. (make-local-variable 'font-lock-defaults)
  1589. (setq font-lock-defaults
  1590. (cond
  1591. ((string< emacs-version "19.30")
  1592. '(cperl-font-lock-keywords-2 nil nil ((?_ . "w"))))
  1593. ((string< emacs-version "19.33") ; Which one to use?
  1594. '((cperl-font-lock-keywords
  1595. cperl-font-lock-keywords-1
  1596. cperl-font-lock-keywords-2) nil nil ((?_ . "w"))))
  1597. (t
  1598. '((cperl-load-font-lock-keywords
  1599. cperl-load-font-lock-keywords-1
  1600. cperl-load-font-lock-keywords-2) nil nil ((?_ . "w"))))))
  1601. (make-local-variable 'cperl-syntax-state)
  1602. (setq cperl-syntax-state nil) ; reset syntaxification cache
  1603. (if cperl-use-syntax-table-text-property
  1604. (if (eval-when-compile (fboundp 'syntax-propertize-rules))
  1605. (progn
  1606. ;; Reset syntaxification cache.
  1607. (set (make-local-variable 'cperl-syntax-done-to) nil)
  1608. (set (make-local-variable 'syntax-propertize-function)
  1609. (lambda (start end)
  1610. (goto-char start)
  1611. ;; Even if cperl-fontify-syntaxically has already gone
  1612. ;; beyond `start', syntax-propertize has just removed
  1613. ;; syntax-table properties between start and end, so we have
  1614. ;; to re-apply them.
  1615. (setq cperl-syntax-done-to start)
  1616. (cperl-fontify-syntaxically end))))
  1617. (make-local-variable 'parse-sexp-lookup-properties)
  1618. ;; Do not introduce variable if not needed, we check it!
  1619. (set 'parse-sexp-lookup-properties t)
  1620. ;; Fix broken font-lock:
  1621. (or (boundp 'font-lock-unfontify-region-function)
  1622. (set 'font-lock-unfontify-region-function
  1623. 'font-lock-default-unfontify-region))
  1624. (unless (featurep 'xemacs) ; Our: just a plug for wrong font-lock
  1625. (make-local-variable 'font-lock-unfontify-region-function)
  1626. (set 'font-lock-unfontify-region-function ; not present with old Emacs
  1627. 'cperl-font-lock-unfontify-region-function))
  1628. (make-local-variable 'cperl-syntax-done-to)
  1629. (setq cperl-syntax-done-to nil) ; reset syntaxification cache
  1630. (make-local-variable 'font-lock-syntactic-keywords)
  1631. (setq font-lock-syntactic-keywords
  1632. (if cperl-syntaxify-by-font-lock
  1633. '((cperl-fontify-syntaxically))
  1634. ;; unless font-lock-syntactic-keywords, font-lock (pre-22.1)
  1635. ;; used to ignore syntax-table text-properties. (t) is a hack
  1636. ;; to make font-lock think that font-lock-syntactic-keywords
  1637. ;; are defined.
  1638. '(t)))))
  1639. (if (boundp 'font-lock-multiline) ; Newer font-lock; use its facilities
  1640. (progn
  1641. (setq cperl-font-lock-multiline t) ; Not localized...
  1642. (set (make-local-variable 'font-lock-multiline) t))
  1643. (make-local-variable 'font-lock-fontify-region-function)
  1644. (set 'font-lock-fontify-region-function ; not present with old Emacs
  1645. 'cperl-font-lock-fontify-region-function))
  1646. (make-local-variable 'font-lock-fontify-region-function)
  1647. (set 'font-lock-fontify-region-function ; not present with old Emacs
  1648. 'cperl-font-lock-fontify-region-function)
  1649. (make-local-variable 'cperl-old-style)
  1650. (if (boundp 'normal-auto-fill-function) ; 19.33 and later
  1651. (set (make-local-variable 'normal-auto-fill-function)
  1652. 'cperl-do-auto-fill)
  1653. (or (fboundp 'cperl-old-auto-fill-mode)
  1654. (progn
  1655. (fset 'cperl-old-auto-fill-mode (symbol-function 'auto-fill-mode))
  1656. (defun auto-fill-mode (&optional arg)
  1657. (interactive "P")
  1658. (eval '(cperl-old-auto-fill-mode arg)) ; Avoid a warning
  1659. (and auto-fill-function (memq major-mode '(perl-mode cperl-mode))
  1660. (setq auto-fill-function 'cperl-do-auto-fill))))))
  1661. (if (cperl-enable-font-lock)
  1662. (if (cperl-val 'cperl-font-lock)
  1663. (progn (or cperl-faces-init (cperl-init-faces))
  1664. (font-lock-mode 1))))
  1665. (set (make-local-variable 'facemenu-add-face-function)
  1666. 'cperl-facemenu-add-face-function) ; XXXX What this guy is for???
  1667. (and (boundp 'msb-menu-cond)
  1668. (not cperl-msb-fixed)
  1669. (cperl-msb-fix))
  1670. (if (fboundp 'easy-menu-add)
  1671. (easy-menu-add cperl-menu)) ; A NOP in Emacs.
  1672. (run-mode-hooks 'cperl-mode-hook)
  1673. (if cperl-hook-after-change
  1674. (add-hook 'after-change-functions 'cperl-after-change-function nil t))
  1675. ;; After hooks since fontification will break this
  1676. (if cperl-pod-here-scan
  1677. (or cperl-syntaxify-by-font-lock
  1678. (progn (or cperl-faces-init (cperl-init-faces-weak))
  1679. (cperl-find-pods-heres)))))
  1680. ;; Fix for perldb - make default reasonable
  1681. (defun cperl-db ()
  1682. (interactive)
  1683. (require 'gud)
  1684. (perldb (read-from-minibuffer "Run perldb (like this): "
  1685. (if (consp gud-perldb-history)
  1686. (car gud-perldb-history)
  1687. (concat "perl " ;;(file-name-nondirectory
  1688. ;; I have problems
  1689. ;; in OS/2
  1690. ;; otherwise
  1691. (buffer-file-name)))
  1692. nil nil
  1693. '(gud-perldb-history . 1))))
  1694. (defun cperl-msb-fix ()
  1695. ;; Adds perl files to msb menu, supposes that msb is already loaded
  1696. (setq cperl-msb-fixed t)
  1697. (let* ((l (length msb-menu-cond))
  1698. (last (nth (1- l) msb-menu-cond))
  1699. (precdr (nthcdr (- l 2) msb-menu-cond)) ; cdr of this is last
  1700. (handle (1- (nth 1 last))))
  1701. (setcdr precdr (list
  1702. (list
  1703. '(memq major-mode '(cperl-mode perl-mode))
  1704. handle
  1705. "Perl Files (%d)")
  1706. last))))
  1707. ;; This is used by indent-for-comment
  1708. ;; to decide how much to indent a comment in CPerl code
  1709. ;; based on its context. Do fallback if comment is found wrong.
  1710. (defvar cperl-wrong-comment)
  1711. (defvar cperl-st-cfence '(14)) ; Comment-fence
  1712. (defvar cperl-st-sfence '(15)) ; String-fence
  1713. (defvar cperl-st-punct '(1))
  1714. (defvar cperl-st-word '(2))
  1715. (defvar cperl-st-bra '(4 . ?\>))
  1716. (defvar cperl-st-ket '(5 . ?\<))
  1717. (defun cperl-comment-indent () ; called at point at supposed comment
  1718. (let ((p (point)) (c (current-column)) was phony)
  1719. (if (and (not cperl-indent-comment-at-column-0)
  1720. (looking-at "^#"))
  1721. 0 ; Existing comment at bol stays there.
  1722. ;; Wrong comment found
  1723. (save-excursion
  1724. (setq was (cperl-to-comment-or-eol)
  1725. phony (eq (get-text-property (point) 'syntax-table)
  1726. cperl-st-cfence))
  1727. (if phony
  1728. (progn ; Too naive???
  1729. (re-search-forward "#\\|$") ; Hmm, what about embedded #?
  1730. (if (eq (preceding-char) ?\#)
  1731. (forward-char -1))
  1732. (setq was nil)))
  1733. (if (= (point) p) ; Our caller found a correct place
  1734. (progn
  1735. (skip-chars-backward " \t")
  1736. (setq was (current-column))
  1737. (if (eq was 0)
  1738. comment-column
  1739. (max (1+ was) ; Else indent at comment column
  1740. comment-column)))
  1741. ;; No, the caller found a random place; we need to edit ourselves
  1742. (if was nil
  1743. (insert comment-start)
  1744. (backward-char (length comment-start)))
  1745. (setq cperl-wrong-comment t)
  1746. (cperl-make-indent comment-column 1) ; Indent min 1
  1747. c)))))
  1748. ;;;(defun cperl-comment-indent-fallback ()
  1749. ;;; "Is called if the standard comment-search procedure fails.
  1750. ;;;Point is at start of real comment."
  1751. ;;; (let ((c (current-column)) target cnt prevc)
  1752. ;;; (if (= c comment-column) nil
  1753. ;;; (setq cnt (skip-chars-backward "[ \t]"))
  1754. ;;; (setq target (max (1+ (setq prevc
  1755. ;;; (current-column))) ; Else indent at comment column
  1756. ;;; comment-column))
  1757. ;;; (if (= c comment-column) nil
  1758. ;;; (delete-backward-char cnt)
  1759. ;;; (while (< prevc target)
  1760. ;;; (insert "\t")
  1761. ;;; (setq prevc (current-column)))
  1762. ;;; (if (> prevc target) (progn (delete-char -1) (setq prevc (current-column))))
  1763. ;;; (while (< prevc target)
  1764. ;;; (insert " ")
  1765. ;;; (setq prevc (current-column)))))))
  1766. (defun cperl-indent-for-comment ()
  1767. "Substitute for `indent-for-comment' in CPerl."
  1768. (interactive)
  1769. (let (cperl-wrong-comment)
  1770. (indent-for-comment)
  1771. (if cperl-wrong-comment ; set by `cperl-comment-indent'
  1772. (progn (cperl-to-comment-or-eol)
  1773. (forward-char (length comment-start))))))
  1774. (defun cperl-comment-region (b e arg)
  1775. "Comment or uncomment each line in the region in CPerl mode.
  1776. See `comment-region'."
  1777. (interactive "r\np")
  1778. (let ((comment-start "#"))
  1779. (comment-region b e arg)))
  1780. (defun cperl-uncomment-region (b e arg)
  1781. "Uncomment or comment each line in the region in CPerl mode.
  1782. See `comment-region'."
  1783. (interactive "r\np")
  1784. (let ((comment-start "#"))
  1785. (comment-region b e (- arg))))
  1786. (defvar cperl-brace-recursing nil)
  1787. (defun cperl-electric-brace (arg &optional only-before)
  1788. "Insert character and correct line's indentation.
  1789. If ONLY-BEFORE and `cperl-auto-newline', will insert newline before the
  1790. place (even in empty line), but not after. If after \")\" and the inserted
  1791. char is \"{\", insert extra newline before only if
  1792. `cperl-extra-newline-before-brace'."
  1793. (interactive "P")
  1794. (let (insertpos
  1795. (other-end (if (and cperl-electric-parens-mark
  1796. (cperl-mark-active)
  1797. (< (mark) (point)))
  1798. (mark)
  1799. nil)))
  1800. (if (and other-end
  1801. (not cperl-brace-recursing)
  1802. (cperl-val 'cperl-electric-parens)
  1803. (>= (save-excursion (cperl-to-comment-or-eol) (point)) (point)))
  1804. ;; Need to insert a matching pair
  1805. (progn
  1806. (save-excursion
  1807. (setq insertpos (point-marker))
  1808. (goto-char other-end)
  1809. (setq last-command-event ?\{)
  1810. (cperl-electric-lbrace arg insertpos))
  1811. (forward-char 1))
  1812. ;; Check whether we close something "usual" with `}'
  1813. (if (and (eq last-command-event ?\})
  1814. (not
  1815. (condition-case nil
  1816. (save-excursion
  1817. (up-list (- (prefix-numeric-value arg)))
  1818. ;;(cperl-after-block-p (point-min))
  1819. (or (cperl-after-expr-p nil "{;)")
  1820. ;; after sub, else, continue
  1821. (cperl-after-block-p nil 'pre)))
  1822. (error nil))))
  1823. ;; Just insert the guy
  1824. (self-insert-command (prefix-numeric-value arg))
  1825. (if (and (not arg) ; No args, end (of empty line or auto)
  1826. (eolp)
  1827. (or (and (null only-before)
  1828. (save-excursion
  1829. (skip-chars-backward " \t")
  1830. (bolp)))
  1831. (and (eq last-command-event ?\{) ; Do not insert newline
  1832. ;; if after ")" and `cperl-extra-newline-before-brace'
  1833. ;; is nil, do not insert extra newline.
  1834. (not cperl-extra-newline-before-brace)
  1835. (save-excursion
  1836. (skip-chars-backward " \t")
  1837. (eq (preceding-char) ?\))))
  1838. (if cperl-auto-newline
  1839. (progn (cperl-indent-line) (newline) t) nil)))
  1840. (progn
  1841. (self-insert-command (prefix-numeric-value arg))
  1842. (cperl-indent-line)
  1843. (if cperl-auto-newline
  1844. (setq insertpos (1- (point))))
  1845. (if (and cperl-auto-newline (null only-before))
  1846. (progn
  1847. (newline)
  1848. (cperl-indent-line)))
  1849. (save-excursion
  1850. (if insertpos (progn (goto-char insertpos)
  1851. (search-forward (make-string
  1852. 1 last-command-event))
  1853. (setq insertpos (1- (point)))))
  1854. (delete-char -1))))
  1855. (if insertpos
  1856. (save-excursion
  1857. (goto-char insertpos)
  1858. (self-insert-command (prefix-numeric-value arg)))
  1859. (self-insert-command (prefix-numeric-value arg)))))))
  1860. (defun cperl-electric-lbrace (arg &optional end)
  1861. "Insert character, correct line's indentation, correct quoting by space."
  1862. (interactive "P")
  1863. (let ((cperl-brace-recursing t)
  1864. (cperl-auto-newline cperl-auto-newline)
  1865. (other-end (or end
  1866. (if (and cperl-electric-parens-mark
  1867. (cperl-mark-active)
  1868. (> (mark) (point)))
  1869. (save-excursion
  1870. (goto-char (mark))
  1871. (point-marker))
  1872. nil)))
  1873. pos after)
  1874. (and (cperl-val 'cperl-electric-lbrace-space)
  1875. (eq (preceding-char) ?$)
  1876. (save-excursion
  1877. (skip-chars-backward "$")
  1878. (looking-at "\\(\\$\\$\\)*\\$\\([^\\$]\\|$\\)"))
  1879. (insert ?\s))
  1880. ;; Check whether we are in comment
  1881. (if (and
  1882. (save-excursion
  1883. (beginning-of-line)
  1884. (not (looking-at "[ \t]*#")))
  1885. (cperl-after-expr-p nil "{;)"))
  1886. nil
  1887. (setq cperl-auto-newline nil))
  1888. (cperl-electric-brace arg)
  1889. (and (cperl-val 'cperl-electric-parens)
  1890. (eq last-command-event ?{)
  1891. (memq last-command-event
  1892. (append cperl-electric-parens-string nil))
  1893. (or (if other-end (goto-char (marker-position other-end)))
  1894. t)
  1895. (setq last-command-event ?} pos (point))
  1896. (progn (cperl-electric-brace arg t)
  1897. (goto-char pos)))))
  1898. (defun cperl-electric-paren (arg)
  1899. "Insert an opening parenthesis or a matching pair of parentheses.
  1900. See `cperl-electric-parens'."
  1901. (interactive "P")
  1902. (let ((beg (point-at-bol))
  1903. (other-end (if (and cperl-electric-parens-mark
  1904. (cperl-mark-active)
  1905. (> (mark) (point)))
  1906. (save-excursion
  1907. (goto-char (mark))
  1908. (point-marker))
  1909. nil)))
  1910. (if (and (cperl-val 'cperl-electric-parens)
  1911. (memq last-command-event
  1912. (append cperl-electric-parens-string nil))
  1913. (>= (save-excursion (cperl-to-comment-or-eol) (point)) (point))
  1914. ;;(not (save-excursion (search-backward "#" beg t)))
  1915. (if (eq last-command-event ?<)
  1916. (progn
  1917. ;; This code is too electric, see Bug#3943.
  1918. ;; (and abbrev-mode ; later it is too late, may be after `for'
  1919. ;; (expand-abbrev))
  1920. (cperl-after-expr-p nil "{;(,:="))
  1921. 1))
  1922. (progn
  1923. (self-insert-command (prefix-numeric-value arg))
  1924. (if other-end (goto-char (marker-position other-end)))
  1925. (insert (make-string
  1926. (prefix-numeric-value arg)
  1927. (cdr (assoc last-command-event '((?{ .?})
  1928. (?[ . ?])
  1929. (?( . ?))
  1930. (?< . ?>))))))
  1931. (forward-char (- (prefix-numeric-value arg))))
  1932. (self-insert-command (prefix-numeric-value arg)))))
  1933. (defun cperl-electric-rparen (arg)
  1934. "Insert a matching pair of parentheses if marking is active.
  1935. If not, or if we are not at the end of marking range, would self-insert.
  1936. Affected by `cperl-electric-parens'."
  1937. (interactive "P")
  1938. (let ((beg (point-at-bol))
  1939. (other-end (if (and cperl-electric-parens-mark
  1940. (cperl-val 'cperl-electric-parens)
  1941. (memq last-command-event
  1942. (append cperl-electric-parens-string nil))
  1943. (cperl-mark-active)
  1944. (< (mark) (point)))
  1945. (mark)
  1946. nil))
  1947. p)
  1948. (if (and other-end
  1949. (cperl-val 'cperl-electric-parens)
  1950. (memq last-command-event '( ?\) ?\] ?\} ?\> ))
  1951. (>= (save-excursion (cperl-to-comment-or-eol) (point)) (point))
  1952. ;;(not (save-excursion (search-backward "#" beg t)))
  1953. )
  1954. (progn
  1955. (self-insert-command (prefix-numeric-value arg))
  1956. (setq p (point))
  1957. (if other-end (goto-char other-end))
  1958. (insert (make-string
  1959. (prefix-numeric-value arg)
  1960. (cdr (assoc last-command-event '((?\} . ?\{)
  1961. (?\] . ?\[)
  1962. (?\) . ?\()
  1963. (?\> . ?\<))))))
  1964. (goto-char (1+ p)))
  1965. (self-insert-command (prefix-numeric-value arg)))))
  1966. (defun cperl-electric-keyword ()
  1967. "Insert a construction appropriate after a keyword.
  1968. Help message may be switched off by setting `cperl-message-electric-keyword'
  1969. to nil."
  1970. (let ((beg (point-at-bol))
  1971. (dollar (and (eq last-command-event ?$)
  1972. (eq this-command 'self-insert-command)))
  1973. (delete (and (memq last-command-event '(?\s ?\n ?\t ?\f))
  1974. (memq this-command '(self-insert-command newline))))
  1975. my do)
  1976. (and (save-excursion
  1977. (condition-case nil
  1978. (progn
  1979. (backward-sexp 1)
  1980. (setq do (looking-at "do\\>")))
  1981. (error nil))
  1982. (cperl-after-expr-p nil "{;:"))
  1983. (save-excursion
  1984. (not
  1985. (re-search-backward
  1986. "[#\"'`]\\|\\<q\\(\\|[wqxr]\\)\\>"
  1987. beg t)))
  1988. (save-excursion (or (not (re-search-backward "^=" nil t))
  1989. (or
  1990. (looking-at "=cut")
  1991. (and cperl-use-syntax-table-text-property
  1992. (not (eq (get-text-property (point)
  1993. 'syntax-type)
  1994. 'pod))))))
  1995. (save-excursion (forward-sexp -1)
  1996. (not (memq (following-char) (append "$@%&*" nil))))
  1997. (progn
  1998. (and (eq (preceding-char) ?y)
  1999. (progn ; "foreachmy"
  2000. (forward-char -2)
  2001. (insert " ")
  2002. (forward-char 2)
  2003. (setq my t dollar t
  2004. delete
  2005. (memq this-command '(self-insert-command newline)))))
  2006. (and dollar (insert " $"))
  2007. (cperl-indent-line)
  2008. ;;(insert " () {\n}")
  2009. (cond
  2010. (cperl-extra-newline-before-brace
  2011. (insert (if do "\n" " ()\n"))
  2012. (insert "{")
  2013. (cperl-indent-line)
  2014. (insert "\n")
  2015. (cperl-indent-line)
  2016. (insert "\n}")
  2017. (and do (insert " while ();")))
  2018. (t
  2019. (insert (if do " {\n} while ();" " () {\n}"))))
  2020. (or (looking-at "[ \t]\\|$") (insert " "))
  2021. (cperl-indent-line)
  2022. (if dollar (progn (search-backward "$")
  2023. (if my
  2024. (forward-char 1)
  2025. (delete-char 1)))
  2026. (search-backward ")")
  2027. (if (eq last-command-event ?\()
  2028. (progn ; Avoid "if (())"
  2029. (delete-char -1)
  2030. (delete-char 1))))
  2031. (if delete
  2032. (cperl-putback-char cperl-del-back-ch))
  2033. (if cperl-message-electric-keyword
  2034. (message "Precede char by C-q to avoid expansion"))))))
  2035. (defun cperl-ensure-newlines (n &optional pos)
  2036. "Make sure there are N newlines after the point."
  2037. (or pos (setq pos (point)))
  2038. (if (looking-at "\n")
  2039. (forward-char 1)
  2040. (insert "\n"))
  2041. (if (> n 1)
  2042. (cperl-ensure-newlines (1- n) pos)
  2043. (goto-char pos)))
  2044. (defun cperl-electric-pod ()
  2045. "Insert a POD chunk appropriate after a =POD directive."
  2046. (let ((delete (and (memq last-command-event '(?\s ?\n ?\t ?\f))
  2047. (memq this-command '(self-insert-command newline))))
  2048. head1 notlast name p really-delete over)
  2049. (and (save-excursion
  2050. (forward-word -1)
  2051. (and
  2052. (eq (preceding-char) ?=)
  2053. (progn
  2054. (setq head1 (looking-at "head1\\>[ \t]*$"))
  2055. (setq over (and (looking-at "over\\>[ \t]*$")
  2056. (not (looking-at "over[ \t]*\n\n\n*=item\\>"))))
  2057. (forward-char -1)
  2058. (bolp))
  2059. (or
  2060. (get-text-property (point) 'in-pod)
  2061. (cperl-after-expr-p nil "{;:")
  2062. (and (re-search-backward "\\(\\`\n?\\|^\n\\)=\\sw+" (point-min) t)
  2063. (not (looking-at "\n*=cut"))
  2064. (or (not cperl-use-syntax-table-text-property)
  2065. (eq (get-text-property (point) 'syntax-type) 'pod))))))
  2066. (progn
  2067. (save-excursion
  2068. (setq notlast (re-search-forward "^\n=" nil t)))
  2069. (or notlast
  2070. (progn
  2071. (insert "\n\n=cut")
  2072. (cperl-ensure-newlines 2)
  2073. (forward-word -2)
  2074. (if (and head1
  2075. (not
  2076. (save-excursion
  2077. (forward-char -1)
  2078. (re-search-backward "\\(\\`\n?\\|\n\n\\)=head1\\>"
  2079. nil t)))) ; Only one
  2080. (progn
  2081. (forward-word 1)
  2082. (setq name (file-name-base)
  2083. p (point))
  2084. (insert " NAME\n\n" name
  2085. " - \n\n=head1 SYNOPSIS\n\n\n\n"
  2086. "=head1 DESCRIPTION")
  2087. (cperl-ensure-newlines 4)
  2088. (goto-char p)
  2089. (forward-word 2)
  2090. (end-of-line)
  2091. (setq really-delete t))
  2092. (forward-word 1))))
  2093. (if over
  2094. (progn
  2095. (setq p (point))
  2096. (insert "\n\n=item \n\n\n\n"
  2097. "=back")
  2098. (cperl-ensure-newlines 2)
  2099. (goto-char p)
  2100. (forward-word 1)
  2101. (end-of-line)
  2102. (setq really-delete t)))
  2103. (if (and delete really-delete)
  2104. (cperl-putback-char cperl-del-back-ch))))))
  2105. (defun cperl-electric-else ()
  2106. "Insert a construction appropriate after a keyword.
  2107. Help message may be switched off by setting `cperl-message-electric-keyword'
  2108. to nil."
  2109. (let ((beg (point-at-bol)))
  2110. (and (save-excursion
  2111. (backward-sexp 1)
  2112. (cperl-after-expr-p nil "{;:"))
  2113. (save-excursion
  2114. (not
  2115. (re-search-backward
  2116. "[#\"'`]\\|\\<q\\(\\|[wqxr]\\)\\>"
  2117. beg t)))
  2118. (save-excursion (or (not (re-search-backward "^=" nil t))
  2119. (looking-at "=cut")
  2120. (and cperl-use-syntax-table-text-property
  2121. (not (eq (get-text-property (point)
  2122. 'syntax-type)
  2123. 'pod)))))
  2124. (progn
  2125. (cperl-indent-line)
  2126. ;;(insert " {\n\n}")
  2127. (cond
  2128. (cperl-extra-newline-before-brace
  2129. (insert "\n")
  2130. (insert "{")
  2131. (cperl-indent-line)
  2132. (insert "\n\n}"))
  2133. (t
  2134. (insert " {\n\n}")))
  2135. (or (looking-at "[ \t]\\|$") (insert " "))
  2136. (cperl-indent-line)
  2137. (forward-line -1)
  2138. (cperl-indent-line)
  2139. (cperl-putback-char cperl-del-back-ch)
  2140. (setq this-command 'cperl-electric-else)
  2141. (if cperl-message-electric-keyword
  2142. (message "Precede char by C-q to avoid expansion"))))))
  2143. (defun cperl-linefeed ()
  2144. "Go to end of line, open a new line and indent appropriately.
  2145. If in POD, insert appropriate lines."
  2146. (interactive)
  2147. (let ((beg (point-at-bol))
  2148. (end (point-at-eol))
  2149. (pos (point)) start over cut res)
  2150. (if (and ; Check if we need to split:
  2151. ; i.e., on a boundary and inside "{...}"
  2152. (save-excursion (cperl-to-comment-or-eol)
  2153. (>= (point) pos)) ; Not in a comment
  2154. (or (save-excursion
  2155. (skip-chars-backward " \t" beg)
  2156. (forward-char -1)
  2157. (looking-at "[;{]")) ; After { or ; + spaces
  2158. (looking-at "[ \t]*}") ; Before }
  2159. (re-search-forward "\\=[ \t]*;" end t)) ; Before spaces + ;
  2160. (save-excursion
  2161. (and
  2162. (eq (car (parse-partial-sexp pos end -1)) -1)
  2163. ; Leave the level of parens
  2164. (looking-at "[,; \t]*\\($\\|#\\)") ; Comma to allow anon subr
  2165. ; Are at end
  2166. (cperl-after-block-p (point-min))
  2167. (progn
  2168. (backward-sexp 1)
  2169. (setq start (point-marker))
  2170. (<= start pos))))) ; Redundant? Are after the
  2171. ; start of parens group.
  2172. (progn
  2173. (skip-chars-backward " \t")
  2174. (or (memq (preceding-char) (append ";{" nil))
  2175. (insert ";"))
  2176. (insert "\n")
  2177. (forward-line -1)
  2178. (cperl-indent-line)
  2179. (goto-char start)
  2180. (or (looking-at "{[ \t]*$") ; If there is a statement
  2181. ; before, move it to separate line
  2182. (progn
  2183. (forward-char 1)
  2184. (insert "\n")
  2185. (cperl-indent-line)))
  2186. (forward-line 1) ; We are on the target line
  2187. (cperl-indent-line)
  2188. (beginning-of-line)
  2189. (or (looking-at "[ \t]*}[,; \t]*$") ; If there is a statement
  2190. ; after, move it to separate line
  2191. (progn
  2192. (end-of-line)
  2193. (search-backward "}" beg)
  2194. (skip-chars-backward " \t")
  2195. (or (memq (preceding-char) (append ";{" nil))
  2196. (insert ";"))
  2197. (insert "\n")
  2198. (cperl-indent-line)
  2199. (forward-line -1)))
  2200. (forward-line -1) ; We are on the line before target
  2201. (end-of-line)
  2202. (newline-and-indent))
  2203. (end-of-line) ; else - no splitting
  2204. (cond
  2205. ((and (looking-at "\n[ \t]*{$")
  2206. (save-excursion
  2207. (skip-chars-backward " \t")
  2208. (eq (preceding-char) ?\)))) ; Probably if () {} group
  2209. ; with an extra newline.
  2210. (forward-line 2)
  2211. (cperl-indent-line))
  2212. ((save-excursion ; In POD header
  2213. (forward-paragraph -1)
  2214. ;; (re-search-backward "\\(\\`\n?\\|\n\n\\)=head1\\b")
  2215. ;; We are after \n now, so look for the rest
  2216. (if (looking-at "\\(\\`\n?\\|\n\\)=\\sw+")
  2217. (progn
  2218. (setq cut (looking-at "\\(\\`\n?\\|\n\\)=cut\\>"))
  2219. (setq over (looking-at "\\(\\`\n?\\|\n\\)=over\\>"))
  2220. t)))
  2221. (if (and over
  2222. (progn
  2223. (forward-paragraph -1)
  2224. (forward-word 1)
  2225. (setq pos (point))
  2226. (setq cut (buffer-substring (point) (point-at-eol)))
  2227. (delete-char (- (point-at-eol) (point)))
  2228. (setq res (expand-abbrev))
  2229. (save-excursion
  2230. (goto-char pos)
  2231. (insert cut))
  2232. res))
  2233. nil
  2234. (cperl-ensure-newlines (if cut 2 4))
  2235. (forward-line 2)))
  2236. ((get-text-property (point) 'in-pod) ; In POD section
  2237. (cperl-ensure-newlines 4)
  2238. (forward-line 2))
  2239. ((looking-at "\n[ \t]*$") ; Next line is empty - use it.
  2240. (forward-line 1)
  2241. (cperl-indent-line))
  2242. (t
  2243. (newline-and-indent))))))
  2244. (defun cperl-electric-semi (arg)
  2245. "Insert character and correct line's indentation."
  2246. (interactive "P")
  2247. (if cperl-auto-newline
  2248. (cperl-electric-terminator arg)
  2249. (self-insert-command (prefix-numeric-value arg))
  2250. (if cperl-autoindent-on-semi
  2251. (cperl-indent-line))))
  2252. (defun cperl-electric-terminator (arg)
  2253. "Insert character and correct line's indentation."
  2254. (interactive "P")
  2255. (let ((end (point))
  2256. (auto (and cperl-auto-newline
  2257. (or (not (eq last-command-event ?:))
  2258. cperl-auto-newline-after-colon)))
  2259. insertpos)
  2260. (if (and ;;(not arg)
  2261. (eolp)
  2262. (not (save-excursion
  2263. (beginning-of-line)
  2264. (skip-chars-forward " \t")
  2265. (or
  2266. ;; Ignore in comment lines
  2267. (= (following-char) ?#)
  2268. ;; Colon is special only after a label
  2269. ;; So quickly rule out most other uses of colon
  2270. ;; and do no indentation for them.
  2271. (and (eq last-command-event ?:)
  2272. (save-excursion
  2273. (forward-word 1)
  2274. (skip-chars-forward " \t")
  2275. (and (< (point) end)
  2276. (progn (goto-char (- end 1))
  2277. (not (looking-at ":"))))))
  2278. (progn
  2279. (beginning-of-defun)
  2280. (let ((pps (parse-partial-sexp (point) end)))
  2281. (or (nth 3 pps) (nth 4 pps) (nth 5 pps))))))))
  2282. (progn
  2283. (self-insert-command (prefix-numeric-value arg))
  2284. ;;(forward-char -1)
  2285. (if auto (setq insertpos (point-marker)))
  2286. ;;(forward-char 1)
  2287. (cperl-indent-line)
  2288. (if auto
  2289. (progn
  2290. (newline)
  2291. (cperl-indent-line)))
  2292. (save-excursion
  2293. (if insertpos (goto-char (1- (marker-position insertpos)))
  2294. (forward-char -1))
  2295. (delete-char 1))))
  2296. (if insertpos
  2297. (save-excursion
  2298. (goto-char insertpos)
  2299. (self-insert-command (prefix-numeric-value arg)))
  2300. (self-insert-command (prefix-numeric-value arg)))))
  2301. (defun cperl-electric-backspace (arg)
  2302. "Backspace, or remove whitespace around the point inserted by an electric key.
  2303. Will untabify if `cperl-electric-backspace-untabify' is non-nil."
  2304. (interactive "p")
  2305. (if (and cperl-auto-newline
  2306. (memq last-command '(cperl-electric-semi
  2307. cperl-electric-terminator
  2308. cperl-electric-lbrace))
  2309. (memq (preceding-char) '(?\s ?\t ?\n)))
  2310. (let (p)
  2311. (if (eq last-command 'cperl-electric-lbrace)
  2312. (skip-chars-forward " \t\n"))
  2313. (setq p (point))
  2314. (skip-chars-backward " \t\n")
  2315. (delete-region (point) p))
  2316. (and (eq last-command 'cperl-electric-else)
  2317. ;; We are removing the whitespace *inside* cperl-electric-else
  2318. (setq this-command 'cperl-electric-else-really))
  2319. (if (and cperl-auto-newline
  2320. (eq last-command 'cperl-electric-else-really)
  2321. (memq (preceding-char) '(?\s ?\t ?\n)))
  2322. (let (p)
  2323. (skip-chars-forward " \t\n")
  2324. (setq p (point))
  2325. (skip-chars-backward " \t\n")
  2326. (delete-region (point) p))
  2327. (if cperl-electric-backspace-untabify
  2328. (backward-delete-char-untabify arg)
  2329. (call-interactively 'delete-backward-char)))))
  2330. (put 'cperl-electric-backspace 'delete-selection 'supersede)
  2331. (defun cperl-inside-parens-p () ;; NOT USED????
  2332. (condition-case ()
  2333. (save-excursion
  2334. (save-restriction
  2335. (narrow-to-region (point)
  2336. (progn (beginning-of-defun) (point)))
  2337. (goto-char (point-max))
  2338. (= (char-after (or (scan-lists (point) -1 1) (point-min))) ?\()))
  2339. (error nil)))
  2340. (defun cperl-indent-command (&optional whole-exp)
  2341. "Indent current line as Perl code, or in some cases insert a tab character.
  2342. If `cperl-tab-always-indent' is non-nil (the default), always indent current
  2343. line. Otherwise, indent the current line only if point is at the left margin
  2344. or in the line's indentation; otherwise insert a tab.
  2345. A numeric argument, regardless of its value,
  2346. means indent rigidly all the lines of the expression starting after point
  2347. so that this line becomes properly indented.
  2348. The relative indentation among the lines of the expression are preserved."
  2349. (interactive "P")
  2350. (cperl-update-syntaxification (point) (point))
  2351. (if whole-exp
  2352. ;; If arg, always indent this line as Perl
  2353. ;; and shift remaining lines of expression the same amount.
  2354. (let ((shift-amt (cperl-indent-line))
  2355. beg end)
  2356. (save-excursion
  2357. (if cperl-tab-always-indent
  2358. (beginning-of-line))
  2359. (setq beg (point))
  2360. (forward-sexp 1)
  2361. (setq end (point))
  2362. (goto-char beg)
  2363. (forward-line 1)
  2364. (setq beg (point)))
  2365. (if (and shift-amt (> end beg))
  2366. (indent-code-rigidly beg end shift-amt "#")))
  2367. (if (and (not cperl-tab-always-indent)
  2368. (save-excursion
  2369. (skip-chars-backward " \t")
  2370. (not (bolp))))
  2371. (insert-tab)
  2372. (cperl-indent-line))))
  2373. (defun cperl-indent-line (&optional parse-data)
  2374. "Indent current line as Perl code.
  2375. Return the amount the indentation changed by."
  2376. (let ((case-fold-search nil)
  2377. (pos (- (point-max) (point)))
  2378. indent i beg shift-amt)
  2379. (setq indent (cperl-calculate-indent parse-data)
  2380. i indent)
  2381. (beginning-of-line)
  2382. (setq beg (point))
  2383. (cond ((or (eq indent nil) (eq indent t))
  2384. (setq indent (current-indentation) i nil))
  2385. ;;((eq indent t) ; Never?
  2386. ;; (setq indent (cperl-calculate-indent-within-comment)))
  2387. ;;((looking-at "[ \t]*#")
  2388. ;; (setq indent 0))
  2389. (t
  2390. (skip-chars-forward " \t")
  2391. (if (listp indent) (setq indent (car indent)))
  2392. (cond ((and (looking-at "[A-Za-z_][A-Za-z_0-9]*:[^:]")
  2393. (not (looking-at "[smy]:\\|tr:")))
  2394. (and (> indent 0)
  2395. (setq indent (max cperl-min-label-indent
  2396. (+ indent cperl-label-offset)))))
  2397. ((= (following-char) ?})
  2398. (setq indent (- indent cperl-indent-level)))
  2399. ((memq (following-char) '(?\) ?\])) ; To line up with opening paren.
  2400. (setq indent (+ indent cperl-close-paren-offset)))
  2401. ((= (following-char) ?{)
  2402. (setq indent (+ indent cperl-brace-offset))))))
  2403. (skip-chars-forward " \t")
  2404. (setq shift-amt (and i (- indent (current-column))))
  2405. (if (or (not shift-amt)
  2406. (zerop shift-amt))
  2407. (if (> (- (point-max) pos) (point))
  2408. (goto-char (- (point-max) pos)))
  2409. ;;;(delete-region beg (point))
  2410. ;;;(indent-to indent)
  2411. (cperl-make-indent indent)
  2412. ;; If initial point was within line's indentation,
  2413. ;; position after the indentation. Else stay at same point in text.
  2414. (if (> (- (point-max) pos) (point))
  2415. (goto-char (- (point-max) pos))))
  2416. shift-amt))
  2417. (defun cperl-after-label ()
  2418. ;; Returns true if the point is after label. Does not do save-excursion.
  2419. (and (eq (preceding-char) ?:)
  2420. (memq (char-syntax (char-after (- (point) 2)))
  2421. '(?w ?_))
  2422. (progn
  2423. (backward-sexp)
  2424. (looking-at "[a-zA-Z_][a-zA-Z0-9_]*:[^:]"))))
  2425. (defun cperl-get-state (&optional parse-start start-state)
  2426. ;; returns list (START STATE DEPTH PRESTART),
  2427. ;; START is a good place to start parsing, or equal to
  2428. ;; PARSE-START if preset,
  2429. ;; STATE is what is returned by `parse-partial-sexp'.
  2430. ;; DEPTH is true is we are immediately after end of block
  2431. ;; which contains START.
  2432. ;; PRESTART is the position basing on which START was found.
  2433. (save-excursion
  2434. (let ((start-point (point)) depth state start prestart)
  2435. (if (and parse-start
  2436. (<= parse-start start-point))
  2437. (goto-char parse-start)
  2438. (beginning-of-defun)
  2439. (setq start-state nil))
  2440. (setq prestart (point))
  2441. (if start-state nil
  2442. ;; Try to go out, if sub is not on the outermost level
  2443. (while (< (point) start-point)
  2444. (setq start (point) parse-start start depth nil
  2445. state (parse-partial-sexp start start-point -1))
  2446. (if (> (car state) -1) nil
  2447. ;; The current line could start like }}}, so the indentation
  2448. ;; corresponds to a different level than what we reached
  2449. (setq depth t)
  2450. (beginning-of-line 2))) ; Go to the next line.
  2451. (if start (goto-char start))) ; Not at the start of file
  2452. (setq start (point))
  2453. (or state (setq state (parse-partial-sexp start start-point -1 nil start-state)))
  2454. (list start state depth prestart))))
  2455. (defvar cperl-look-for-prop '((pod in-pod) (here-doc-delim here-doc-group)))
  2456. (defun cperl-beginning-of-property (p prop &optional lim)
  2457. "Given that P has a property PROP, find where the property starts.
  2458. Will not look before LIM."
  2459. ;;; XXXX What to do at point-max???
  2460. (or (previous-single-property-change (cperl-1+ p) prop lim)
  2461. (point-min))
  2462. ;;; (cond ((eq p (point-min))
  2463. ;;; p)
  2464. ;;; ((and lim (<= p lim))
  2465. ;;; p)
  2466. ;;; ((not (get-text-property (1- p) prop))
  2467. ;;; p)
  2468. ;;; (t (or (previous-single-property-change p look-prop lim)
  2469. ;;; (point-min))))
  2470. )
  2471. (defun cperl-sniff-for-indent (&optional parse-data) ; was parse-start
  2472. ;; the sniffer logic to understand what the current line MEANS.
  2473. (cperl-update-syntaxification (point) (point))
  2474. (let ((res (get-text-property (point) 'syntax-type)))
  2475. (save-excursion
  2476. (cond
  2477. ((and (memq res '(pod here-doc here-doc-delim format))
  2478. (not (get-text-property (point) 'indentable)))
  2479. (vector res))
  2480. ;; before start of POD - whitespace found since do not have 'pod!
  2481. ((looking-at "[ \t]*\n=")
  2482. (error "Spaces before POD section!"))
  2483. ((and (not cperl-indent-left-aligned-comments)
  2484. (looking-at "^#"))
  2485. [comment-special:at-beginning-of-line])
  2486. ((get-text-property (point) 'in-pod)
  2487. [in-pod])
  2488. (t
  2489. (beginning-of-line)
  2490. (let* ((indent-point (point))
  2491. (char-after-pos (save-excursion
  2492. (skip-chars-forward " \t")
  2493. (point)))
  2494. (char-after (char-after char-after-pos))
  2495. (pre-indent-point (point))
  2496. p prop look-prop is-block delim)
  2497. (save-excursion ; Know we are not in POD, find appropriate pos before
  2498. (cperl-backward-to-noncomment nil)
  2499. (setq p (max (point-min) (1- (point)))
  2500. prop (get-text-property p 'syntax-type)
  2501. look-prop (or (nth 1 (assoc prop cperl-look-for-prop))
  2502. 'syntax-type))
  2503. (if (memq prop '(pod here-doc format here-doc-delim))
  2504. (progn
  2505. (goto-char (cperl-beginning-of-property p look-prop))
  2506. (beginning-of-line)
  2507. (setq pre-indent-point (point)))))
  2508. (goto-char pre-indent-point) ; Orig line skipping preceding pod/etc
  2509. (let* ((case-fold-search nil)
  2510. (s-s (cperl-get-state (car parse-data) (nth 1 parse-data)))
  2511. (start (or (nth 2 parse-data) ; last complete sexp terminated
  2512. (nth 0 s-s))) ; Good place to start parsing
  2513. (state (nth 1 s-s))
  2514. (containing-sexp (car (cdr state)))
  2515. old-indent)
  2516. (if (and
  2517. ;;containing-sexp ;; We are buggy at toplevel :-(
  2518. parse-data)
  2519. (progn
  2520. (setcar parse-data pre-indent-point)
  2521. (setcar (cdr parse-data) state)
  2522. (or (nth 2 parse-data)
  2523. (setcar (cddr parse-data) start))
  2524. ;; Before this point: end of statement
  2525. (setq old-indent (nth 3 parse-data))))
  2526. (cond ((get-text-property (point) 'indentable)
  2527. ;; indent to "after" the surrounding open
  2528. ;; (same offset as `cperl-beautify-regexp-piece'),
  2529. ;; skip blanks if we do not close the expression.
  2530. (setq delim ; We do not close the expression
  2531. (get-text-property
  2532. (cperl-1+ char-after-pos) 'indentable)
  2533. p (1+ (cperl-beginning-of-property
  2534. (point) 'indentable))
  2535. is-block ; misused for: preceding line in REx
  2536. (save-excursion ; Find preceding line
  2537. (cperl-backward-to-noncomment p)
  2538. (beginning-of-line)
  2539. (if (<= (point) p)
  2540. (progn ; get indent from the first line
  2541. (goto-char p)
  2542. (skip-chars-forward " \t")
  2543. (if (memq (char-after (point))
  2544. (append "#\n" nil))
  2545. nil ; Can't use indentation of this line...
  2546. (point)))
  2547. (skip-chars-forward " \t")
  2548. (point)))
  2549. prop (parse-partial-sexp p char-after-pos))
  2550. (cond ((not delim) ; End the REx, ignore is-block
  2551. (vector 'indentable 'terminator p is-block))
  2552. (is-block ; Indent w.r.t. preceding line
  2553. (vector 'indentable 'cont-line char-after-pos
  2554. is-block char-after p))
  2555. (t ; No preceding line...
  2556. (vector 'indentable 'first-line p))))
  2557. ((get-text-property char-after-pos 'REx-part2)
  2558. (vector 'REx-part2 (point)))
  2559. ((nth 4 state)
  2560. [comment])
  2561. ((nth 3 state)
  2562. [string])
  2563. ;; XXXX Do we need to special-case this?
  2564. ((null containing-sexp)
  2565. ;; Line is at top level. May be data or function definition,
  2566. ;; or may be function argument declaration.
  2567. ;; Indent like the previous top level line
  2568. ;; unless that ends in a closeparen without semicolon,
  2569. ;; in which case this line is the first argument decl.
  2570. (skip-chars-forward " \t")
  2571. (cperl-backward-to-noncomment (or old-indent (point-min)))
  2572. (setq state
  2573. (or (bobp)
  2574. (eq (point) old-indent) ; old-indent was at comment
  2575. (eq (preceding-char) ?\;)
  2576. ;; Had ?\) too
  2577. (and (eq (preceding-char) ?\})
  2578. (cperl-after-block-and-statement-beg
  2579. (point-min))) ; Was start - too close
  2580. (memq char-after (append ")]}" nil))
  2581. (and (eq (preceding-char) ?\:) ; label
  2582. (progn
  2583. (forward-sexp -1)
  2584. (skip-chars-backward " \t")
  2585. (looking-at "[ \t]*[a-zA-Z_][a-zA-Z_0-9]*[ \t]*:")))
  2586. (get-text-property (point) 'first-format-line)))
  2587. ;; Look at previous line that's at column 0
  2588. ;; to determine whether we are in top-level decls
  2589. ;; or function's arg decls. Set basic-indent accordingly.
  2590. ;; Now add a little if this is a continuation line.
  2591. (and state
  2592. parse-data
  2593. (not (eq char-after ?\C-j))
  2594. (setcdr (cddr parse-data)
  2595. (list pre-indent-point)))
  2596. (vector 'toplevel start char-after state (nth 2 s-s)))
  2597. ((not
  2598. (or (setq is-block
  2599. (and (setq delim (= (char-after containing-sexp) ?{))
  2600. (save-excursion ; Is it a hash?
  2601. (goto-char containing-sexp)
  2602. (cperl-block-p))))
  2603. cperl-indent-parens-as-block))
  2604. ;; group is an expression, not a block:
  2605. ;; indent to just after the surrounding open parens,
  2606. ;; skip blanks if we do not close the expression.
  2607. (goto-char (1+ containing-sexp))
  2608. (or (memq char-after
  2609. (append (if delim "}" ")]}") nil))
  2610. (looking-at "[ \t]*\\(#\\|$\\)")
  2611. (skip-chars-forward " \t"))
  2612. (setq old-indent (point)) ; delim=is-brace
  2613. (vector 'in-parens char-after (point) delim containing-sexp))
  2614. (t
  2615. ;; Statement level. Is it a continuation or a new statement?
  2616. ;; Find previous non-comment character.
  2617. (goto-char pre-indent-point) ; Skip one level of POD/etc
  2618. (cperl-backward-to-noncomment containing-sexp)
  2619. ;; Back up over label lines, since they don't
  2620. ;; affect whether our line is a continuation.
  2621. ;; (Had \, too)
  2622. (while;;(or (eq (preceding-char) ?\,)
  2623. (and (eq (preceding-char) ?:)
  2624. (or;;(eq (char-after (- (point) 2)) ?\') ; ????
  2625. (memq (char-syntax (char-after (- (point) 2)))
  2626. '(?w ?_))))
  2627. ;;)
  2628. ;; This is always FALSE?
  2629. (if (eq (preceding-char) ?\,)
  2630. ;; Will go to beginning of line, essentially.
  2631. ;; Will ignore embedded sexpr XXXX.
  2632. (cperl-backward-to-start-of-continued-exp containing-sexp))
  2633. (beginning-of-line)
  2634. (cperl-backward-to-noncomment containing-sexp))
  2635. ;; Now we get non-label preceding the indent point
  2636. (if (not (or (eq (1- (point)) containing-sexp)
  2637. (memq (preceding-char)
  2638. (append (if is-block " ;{" " ,;{") '(nil)))
  2639. (and (eq (preceding-char) ?\})
  2640. (cperl-after-block-and-statement-beg
  2641. containing-sexp))
  2642. (get-text-property (point) 'first-format-line)))
  2643. ;; This line is continuation of preceding line's statement;
  2644. ;; indent `cperl-continued-statement-offset' more than the
  2645. ;; previous line of the statement.
  2646. ;;
  2647. ;; There might be a label on this line, just
  2648. ;; consider it bad style and ignore it.
  2649. (progn
  2650. (cperl-backward-to-start-of-continued-exp containing-sexp)
  2651. (vector 'continuation (point) char-after is-block delim))
  2652. ;; This line starts a new statement.
  2653. ;; Position following last unclosed open brace
  2654. (goto-char containing-sexp)
  2655. ;; Is line first statement after an open-brace?
  2656. (or
  2657. ;; If no, find that first statement and indent like
  2658. ;; it. If the first statement begins with label, do
  2659. ;; not believe when the indentation of the label is too
  2660. ;; small.
  2661. (save-excursion
  2662. (forward-char 1)
  2663. (let ((colon-line-end 0))
  2664. (while
  2665. (progn (skip-chars-forward " \t\n")
  2666. ;; s: foo : bar :x is NOT label
  2667. (and (looking-at "#\\|\\([a-zA-Z0-9_$]+\\):[^:]\\|=[a-zA-Z]")
  2668. (not (looking-at "[sym]:\\|tr:"))))
  2669. ;; Skip over comments and labels following openbrace.
  2670. (cond ((= (following-char) ?\#)
  2671. (forward-line 1))
  2672. ((= (following-char) ?\=)
  2673. (goto-char
  2674. (or (next-single-property-change (point) 'in-pod)
  2675. (point-max)))) ; do not loop if no syntaxification
  2676. ;; label:
  2677. (t
  2678. (setq colon-line-end (point-at-eol))
  2679. (search-forward ":"))))
  2680. ;; We are at beginning of code (NOT label or comment)
  2681. ;; First, the following code counts
  2682. ;; if it is before the line we want to indent.
  2683. (and (< (point) indent-point)
  2684. (vector 'have-prev-sibling (point) colon-line-end
  2685. containing-sexp))))
  2686. (progn
  2687. ;; If no previous statement,
  2688. ;; indent it relative to line brace is on.
  2689. ;; For open-braces not the first thing in a line,
  2690. ;; add in cperl-brace-imaginary-offset.
  2691. ;; If first thing on a line: ?????
  2692. ;; Move back over whitespace before the openbrace.
  2693. (setq ; brace first thing on a line
  2694. old-indent (progn (skip-chars-backward " \t") (bolp)))
  2695. ;; Should we indent w.r.t. earlier than start?
  2696. ;; Move to start of control group, possibly on a different line
  2697. (or cperl-indent-wrt-brace
  2698. (cperl-backward-to-noncomment (point-min)))
  2699. ;; If the openbrace is preceded by a parenthesized exp,
  2700. ;; move to the beginning of that;
  2701. (if (eq (preceding-char) ?\))
  2702. (progn
  2703. (forward-sexp -1)
  2704. (cperl-backward-to-noncomment (point-min))))
  2705. ;; In the case it starts a subroutine, indent with
  2706. ;; respect to `sub', not with respect to the
  2707. ;; first thing on the line, say in the case of
  2708. ;; anonymous sub in a hash.
  2709. (if (and;; Is it a sub in group starting on this line?
  2710. (cond ((get-text-property (point) 'attrib-group)
  2711. (goto-char (cperl-beginning-of-property
  2712. (point) 'attrib-group)))
  2713. ((eq (preceding-char) ?b)
  2714. (forward-sexp -1)
  2715. (looking-at "sub\\>")))
  2716. (setq p (nth 1 ; start of innermost containing list
  2717. (parse-partial-sexp
  2718. (point-at-bol)
  2719. (point)))))
  2720. (progn
  2721. (goto-char (1+ p)) ; enclosing block on the same line
  2722. (skip-chars-forward " \t")
  2723. (vector 'code-start-in-block containing-sexp char-after
  2724. (and delim (not is-block)) ; is a HASH
  2725. old-indent ; brace first thing on a line
  2726. t (point) ; have something before...
  2727. )
  2728. ;;(current-column)
  2729. )
  2730. ;; Get initial indentation of the line we are on.
  2731. ;; If line starts with label, calculate label indentation
  2732. (vector 'code-start-in-block containing-sexp char-after
  2733. (and delim (not is-block)) ; is a HASH
  2734. old-indent ; brace first thing on a line
  2735. nil (point))))))))))))))) ; nothing interesting before
  2736. (defvar cperl-indent-rules-alist
  2737. '((pod nil) ; via `syntax-type' property
  2738. (here-doc nil) ; via `syntax-type' property
  2739. (here-doc-delim nil) ; via `syntax-type' property
  2740. (format nil) ; via `syntax-type' property
  2741. (in-pod nil) ; via `in-pod' property
  2742. (comment-special:at-beginning-of-line nil)
  2743. (string t)
  2744. (comment nil))
  2745. "Alist of indentation rules for CPerl mode.
  2746. The values mean:
  2747. nil: do not indent;
  2748. number: add this amount of indentation.")
  2749. (defun cperl-calculate-indent (&optional parse-data) ; was parse-start
  2750. "Return appropriate indentation for current line as Perl code.
  2751. In usual case returns an integer: the column to indent to.
  2752. Returns nil if line starts inside a string, t if in a comment.
  2753. Will not correct the indentation for labels, but will correct it for braces
  2754. and closing parentheses and brackets."
  2755. ;; This code is still a broken architecture: in some cases we need to
  2756. ;; compensate for some modifications which `cperl-indent-line' will add later
  2757. (save-excursion
  2758. (let ((i (cperl-sniff-for-indent parse-data)) what p)
  2759. (cond
  2760. ;;((or (null i) (eq i t) (numberp i))
  2761. ;; i)
  2762. ((vectorp i)
  2763. (setq what (assoc (elt i 0) cperl-indent-rules-alist))
  2764. (cond
  2765. (what (cadr what)) ; Load from table
  2766. ;;
  2767. ;; Indenters for regular expressions with //x and qw()
  2768. ;;
  2769. ((eq 'REx-part2 (elt i 0)) ;; [self start] start of /REP in s//REP/x
  2770. (goto-char (elt i 1))
  2771. (condition-case nil ; Use indentation of the 1st part
  2772. (forward-sexp -1))
  2773. (current-column))
  2774. ((eq 'indentable (elt i 0)) ; Indenter for REGEXP qw() etc
  2775. (cond ;;; [indentable terminator start-pos is-block]
  2776. ((eq 'terminator (elt i 1)) ; Lone terminator of "indentable string"
  2777. (goto-char (elt i 2)) ; After opening parens
  2778. (1- (current-column)))
  2779. ((eq 'first-line (elt i 1)); [indentable first-line start-pos]
  2780. (goto-char (elt i 2))
  2781. (+ (or cperl-regexp-indent-step cperl-indent-level)
  2782. -1
  2783. (current-column)))
  2784. ((eq 'cont-line (elt i 1)); [indentable cont-line pos prev-pos first-char start-pos]
  2785. ;; Indent as the level after closing parens
  2786. (goto-char (elt i 2)) ; indent line
  2787. (skip-chars-forward " \t)") ; Skip closing parens
  2788. (setq p (point))
  2789. (goto-char (elt i 3)) ; previous line
  2790. (skip-chars-forward " \t)") ; Skip closing parens
  2791. ;; Number of parens in between:
  2792. (setq p (nth 0 (parse-partial-sexp (point) p))
  2793. what (elt i 4)) ; First char on current line
  2794. (goto-char (elt i 3)) ; previous line
  2795. (+ (* p (or cperl-regexp-indent-step cperl-indent-level))
  2796. (cond ((eq what ?\) )
  2797. (- cperl-close-paren-offset)) ; compensate
  2798. ((eq what ?\| )
  2799. (- (or cperl-regexp-indent-step cperl-indent-level)))
  2800. (t 0))
  2801. (if (eq (following-char) ?\| )
  2802. (or cperl-regexp-indent-step cperl-indent-level)
  2803. 0)
  2804. (current-column)))
  2805. (t
  2806. (error "Unrecognized value of indent: %s" i))))
  2807. ;;
  2808. ;; Indenter for stuff at toplevel
  2809. ;;
  2810. ((eq 'toplevel (elt i 0)) ;; [toplevel start char-after state immed-after-block]
  2811. (+ (save-excursion ; To beg-of-defun, or end of last sexp
  2812. (goto-char (elt i 1)) ; start = Good place to start parsing
  2813. (- (current-indentation) ;
  2814. (if (elt i 4) cperl-indent-level 0))) ; immed-after-block
  2815. (if (eq (elt i 2) ?{) cperl-continued-brace-offset 0) ; char-after
  2816. ;; Look at previous line that's at column 0
  2817. ;; to determine whether we are in top-level decls
  2818. ;; or function's arg decls. Set basic-indent accordingly.
  2819. ;; Now add a little if this is a continuation line.
  2820. (if (elt i 3) ; state (XXX What is the semantic???)
  2821. 0
  2822. cperl-continued-statement-offset)))
  2823. ;;
  2824. ;; Indenter for stuff in "parentheses" (or brackets, braces-as-hash)
  2825. ;;
  2826. ((eq 'in-parens (elt i 0))
  2827. ;; in-parens char-after old-indent-point is-brace containing-sexp
  2828. ;; group is an expression, not a block:
  2829. ;; indent to just after the surrounding open parens,
  2830. ;; skip blanks if we do not close the expression.
  2831. (+ (progn
  2832. (goto-char (elt i 2)) ; old-indent-point
  2833. (current-column))
  2834. (if (and (elt i 3) ; is-brace
  2835. (eq (elt i 1) ?\})) ; char-after
  2836. ;; Correct indentation of trailing ?\}
  2837. (+ cperl-indent-level cperl-close-paren-offset)
  2838. 0)))
  2839. ;;
  2840. ;; Indenter for continuation lines
  2841. ;;
  2842. ((eq 'continuation (elt i 0))
  2843. ;; [continuation statement-start char-after is-block is-brace]
  2844. (goto-char (elt i 1)) ; statement-start
  2845. (+ (if (or (memq (elt i 2) (append "}])" nil)) ; char-after
  2846. (eq 'continuation ; do not stagger continuations
  2847. (elt (cperl-sniff-for-indent parse-data) 0)))
  2848. 0 ; Closing parenthesis or continuation of a continuation
  2849. cperl-continued-statement-offset)
  2850. (if (or (elt i 3) ; is-block
  2851. (not (elt i 4)) ; is-brace
  2852. (not (eq (elt i 2) ?\}))) ; char-after
  2853. 0
  2854. ;; Now it is a hash reference
  2855. (+ cperl-indent-level cperl-close-paren-offset))
  2856. ;; Labels do not take :: ...
  2857. (if (looking-at "\\(\\w\\|_\\)+[ \t]*:")
  2858. (if (> (current-indentation) cperl-min-label-indent)
  2859. (- (current-indentation) cperl-label-offset)
  2860. ;; Do not move `parse-data', this should
  2861. ;; be quick anyway (this comment comes
  2862. ;; from different location):
  2863. (cperl-calculate-indent))
  2864. (current-column))
  2865. (if (eq (elt i 2) ?\{) ; char-after
  2866. cperl-continued-brace-offset 0)))
  2867. ;;
  2868. ;; Indenter for lines in a block which are not leading lines
  2869. ;;
  2870. ((eq 'have-prev-sibling (elt i 0))
  2871. ;; [have-prev-sibling sibling-beg colon-line-end block-start]
  2872. (goto-char (elt i 1)) ; sibling-beg
  2873. (if (> (elt i 2) (point)) ; colon-line-end; have label before point
  2874. (if (> (current-indentation)
  2875. cperl-min-label-indent)
  2876. (- (current-indentation) cperl-label-offset)
  2877. ;; Do not believe: `max' was involved in calculation of indent
  2878. (+ cperl-indent-level
  2879. (save-excursion
  2880. (goto-char (elt i 3)) ; block-start
  2881. (current-indentation))))
  2882. (current-column)))
  2883. ;;
  2884. ;; Indenter for the first line in a block
  2885. ;;
  2886. ((eq 'code-start-in-block (elt i 0))
  2887. ;;[code-start-in-block before-brace char-after
  2888. ;; is-a-HASH-ref brace-is-first-thing-on-a-line
  2889. ;; group-starts-before-start-of-sub start-of-control-group]
  2890. (goto-char (elt i 1))
  2891. ;; For open brace in column zero, don't let statement
  2892. ;; start there too. If cperl-indent-level=0,
  2893. ;; use cperl-brace-offset + cperl-continued-statement-offset instead.
  2894. (+ (if (and (bolp) (zerop cperl-indent-level))
  2895. (+ cperl-brace-offset cperl-continued-statement-offset)
  2896. cperl-indent-level)
  2897. (if (and (elt i 3) ; is-a-HASH-ref
  2898. (eq (elt i 2) ?\})) ; char-after: End of a hash reference
  2899. (+ cperl-indent-level cperl-close-paren-offset)
  2900. 0)
  2901. ;; Unless openbrace is the first nonwhite thing on the line,
  2902. ;; add the cperl-brace-imaginary-offset.
  2903. (if (elt i 4) 0 ; brace-is-first-thing-on-a-line
  2904. cperl-brace-imaginary-offset)
  2905. (progn
  2906. (goto-char (elt i 6)) ; start-of-control-group
  2907. (if (elt i 5) ; group-starts-before-start-of-sub
  2908. (current-column)
  2909. ;; Get initial indentation of the line we are on.
  2910. ;; If line starts with label, calculate label indentation
  2911. (if (save-excursion
  2912. (beginning-of-line)
  2913. (looking-at "[ \t]*[a-zA-Z_][a-zA-Z_0-9]*:[^:]"))
  2914. (if (> (current-indentation) cperl-min-label-indent)
  2915. (- (current-indentation) cperl-label-offset)
  2916. ;; Do not move `parse-data', this should
  2917. ;; be quick anyway:
  2918. (cperl-calculate-indent))
  2919. (current-indentation))))))
  2920. (t
  2921. (error "Unrecognized value of indent: %s" i))))
  2922. (t
  2923. (error "Got strange value of indent: %s" i))))))
  2924. (defun cperl-calculate-indent-within-comment ()
  2925. "Return the indentation amount for line, assuming that
  2926. the current line is to be regarded as part of a block comment."
  2927. (let (end star-start)
  2928. (save-excursion
  2929. (beginning-of-line)
  2930. (skip-chars-forward " \t")
  2931. (setq end (point))
  2932. (and (= (following-char) ?#)
  2933. (forward-line -1)
  2934. (cperl-to-comment-or-eol)
  2935. (setq end (point)))
  2936. (goto-char end)
  2937. (current-column))))
  2938. (defun cperl-to-comment-or-eol ()
  2939. "Go to position before comment on the current line, or to end of line.
  2940. Returns true if comment is found. In POD will not move the point."
  2941. ;; If the line is inside other syntax groups (qq-style strings, HERE-docs)
  2942. ;; then looks for literal # or end-of-line.
  2943. (let (state stop-in cpoint (lim (point-at-eol)) pr e)
  2944. (or cperl-font-locking
  2945. (cperl-update-syntaxification lim lim))
  2946. (beginning-of-line)
  2947. (if (setq pr (get-text-property (point) 'syntax-type))
  2948. (setq e (next-single-property-change (point) 'syntax-type nil (point-max))))
  2949. (if (or (eq pr 'pod)
  2950. (if (or (not e) (> e lim)) ; deep inside a group
  2951. (re-search-forward "\\=[ \t]*\\(#\\|$\\)" lim t)))
  2952. (if (eq (preceding-char) ?\#) (progn (backward-char 1) t))
  2953. ;; Else - need to do it the hard way
  2954. (and (and e (<= e lim))
  2955. (goto-char e))
  2956. (while (not stop-in)
  2957. (setq state (parse-partial-sexp (point) lim nil nil nil t))
  2958. ; stop at comment
  2959. ;; If fails (beginning-of-line inside sexp), then contains not-comment
  2960. (if (nth 4 state) ; After `#';
  2961. ; (nth 2 state) can be
  2962. ; beginning of m,s,qq and so
  2963. ; on
  2964. (if (nth 2 state)
  2965. (progn
  2966. (setq cpoint (point))
  2967. (goto-char (nth 2 state))
  2968. (cond
  2969. ((looking-at "\\(s\\|tr\\)\\>")
  2970. (or (re-search-forward
  2971. "\\=\\w+[ \t]*#\\([^\n\\\\#]\\|\\\\[\\\\#]\\)*#\\([^\n\\\\#]\\|\\\\[\\\\#]\\)*"
  2972. lim 'move)
  2973. (setq stop-in t)))
  2974. ((looking-at "\\(m\\|q\\([qxwr]\\)?\\)\\>")
  2975. (or (re-search-forward
  2976. "\\=\\w+[ \t]*#\\([^\n\\\\#]\\|\\\\[\\\\#]\\)*#"
  2977. lim 'move)
  2978. (setq stop-in t)))
  2979. (t ; It was fair comment
  2980. (setq stop-in t) ; Finish
  2981. (goto-char (1- cpoint)))))
  2982. (setq stop-in t) ; Finish
  2983. (forward-char -1))
  2984. (setq stop-in t))) ; Finish
  2985. (nth 4 state))))
  2986. (defsubst cperl-modify-syntax-type (at how)
  2987. (if (< at (point-max))
  2988. (progn
  2989. (put-text-property at (1+ at) 'syntax-table how)
  2990. (put-text-property at (1+ at) 'rear-nonsticky '(syntax-table)))))
  2991. (defun cperl-protect-defun-start (s e)
  2992. ;; C code looks for "^\\s(" to skip comment backward in "hard" situations
  2993. (save-excursion
  2994. (goto-char s)
  2995. (while (re-search-forward "^\\s(" e 'to-end)
  2996. (put-text-property (1- (point)) (point) 'syntax-table cperl-st-punct))))
  2997. (defun cperl-commentify (bb e string &optional noface)
  2998. (if cperl-use-syntax-table-text-property
  2999. (if (eq noface 'n) ; Only immediate
  3000. nil
  3001. ;; We suppose that e is _after_ the end of construction, as after eol.
  3002. (setq string (if string cperl-st-sfence cperl-st-cfence))
  3003. (if (> bb (- e 2))
  3004. ;; one-char string/comment?!
  3005. (cperl-modify-syntax-type bb cperl-st-punct)
  3006. (cperl-modify-syntax-type bb string)
  3007. (cperl-modify-syntax-type (1- e) string))
  3008. (if (and (eq string cperl-st-sfence) (> (- e 2) bb))
  3009. (put-text-property (1+ bb) (1- e)
  3010. 'syntax-table cperl-string-syntax-table))
  3011. (cperl-protect-defun-start bb e))
  3012. ;; Fontify
  3013. (or noface
  3014. (not cperl-pod-here-fontify)
  3015. (put-text-property bb e 'face (if string 'font-lock-string-face
  3016. 'font-lock-comment-face)))))
  3017. (defvar cperl-starters '(( ?\( . ?\) )
  3018. ( ?\[ . ?\] )
  3019. ( ?\{ . ?\} )
  3020. ( ?\< . ?\> )))
  3021. (defun cperl-cached-syntax-table (st)
  3022. "Get a syntax table cached in ST, or create and cache into ST a syntax table.
  3023. All the entries of the syntax table are \".\", except for a backslash, which
  3024. is quoting."
  3025. (if (car-safe st)
  3026. (car st)
  3027. (setcar st (make-syntax-table))
  3028. (setq st (car st))
  3029. (let ((i 0))
  3030. (while (< i 256)
  3031. (modify-syntax-entry i "." st)
  3032. (setq i (1+ i))))
  3033. (modify-syntax-entry ?\\ "\\" st)
  3034. st))
  3035. (defun cperl-forward-re (lim end is-2arg st-l err-l argument
  3036. &optional ostart oend)
  3037. "Find the end of a regular expression or a stringish construct (q[] etc).
  3038. The point should be before the starting delimiter.
  3039. Goes to LIM if none is found. If IS-2ARG is non-nil, assumes that it
  3040. is s/// or tr/// like expression. If END is nil, generates an error
  3041. message if needed. If SET-ST is non-nil, will use (or generate) a
  3042. cached syntax table in ST-L. If ERR-L is non-nil, will store the
  3043. error message in its CAR (unless it already contains some error
  3044. message). ARGUMENT should be the name of the construct (used in error
  3045. messages). OSTART, OEND may be set in recursive calls when processing
  3046. the second argument of 2ARG construct.
  3047. Works *before* syntax recognition is done. In IS-2ARG situation may
  3048. modify syntax-type text property if the situation is too hard."
  3049. (let (b starter ender st i i2 go-forward reset-st set-st)
  3050. (skip-chars-forward " \t")
  3051. ;; ender means matching-char matcher.
  3052. (setq b (point)
  3053. starter (if (eobp) 0 (char-after b))
  3054. ender (cdr (assoc starter cperl-starters)))
  3055. ;; What if starter == ?\\ ????
  3056. (setq st (cperl-cached-syntax-table st-l))
  3057. (setq set-st t)
  3058. ;; Whether we have an intermediate point
  3059. (setq i nil)
  3060. ;; Prepare the syntax table:
  3061. (if (not ender) ; m/blah/, s/x//, s/x/y/
  3062. (modify-syntax-entry starter "$" st)
  3063. (modify-syntax-entry starter (concat "(" (list ender)) st)
  3064. (modify-syntax-entry ender (concat ")" (list starter)) st))
  3065. (condition-case bb
  3066. (progn
  3067. ;; We use `$' syntax class to find matching stuff, but $$
  3068. ;; is recognized the same as $, so we need to check this manually.
  3069. (if (and (eq starter (char-after (cperl-1+ b)))
  3070. (not ender))
  3071. ;; $ has TeXish matching rules, so $$ equiv $...
  3072. (forward-char 2)
  3073. (setq reset-st (syntax-table))
  3074. (set-syntax-table st)
  3075. (forward-sexp 1)
  3076. (if (<= (point) (1+ b))
  3077. (error "Unfinished regular expression"))
  3078. (set-syntax-table reset-st)
  3079. (setq reset-st nil)
  3080. ;; Now the problem is with m;blah;;
  3081. (and (not ender)
  3082. (eq (preceding-char)
  3083. (char-after (- (point) 2)))
  3084. (save-excursion
  3085. (forward-char -2)
  3086. (= 0 (% (skip-chars-backward "\\\\") 2)))
  3087. (forward-char -1)))
  3088. ;; Now we are after the first part.
  3089. (and is-2arg ; Have trailing part
  3090. (not ender)
  3091. (eq (following-char) starter) ; Empty trailing part
  3092. (progn
  3093. (or (eq (char-syntax (following-char)) ?.)
  3094. ;; Make trailing letter into punctuation
  3095. (cperl-modify-syntax-type (point) cperl-st-punct))
  3096. (setq is-2arg nil go-forward t))) ; Ignore the tail
  3097. (if is-2arg ; Not number => have second part
  3098. (progn
  3099. (setq i (point) i2 i)
  3100. (if ender
  3101. (if (memq (following-char) '(?\s ?\t ?\n ?\f))
  3102. (progn
  3103. (if (looking-at "[ \t\n\f]+\\(#[^\n]*\n[ \t\n\f]*\\)+")
  3104. (goto-char (match-end 0))
  3105. (skip-chars-forward " \t\n\f"))
  3106. (setq i2 (point))))
  3107. (forward-char -1))
  3108. (modify-syntax-entry starter (if (eq starter ?\\) "\\" ".") st)
  3109. (if ender (modify-syntax-entry ender "." st))
  3110. (setq set-st nil)
  3111. (setq ender (cperl-forward-re lim end nil st-l err-l
  3112. argument starter ender)
  3113. ender (nth 2 ender)))))
  3114. (error (goto-char lim)
  3115. (setq set-st nil)
  3116. (if reset-st
  3117. (set-syntax-table reset-st))
  3118. (or end
  3119. (and cperl-brace-recursing
  3120. (or (eq ostart ?\{)
  3121. (eq starter ?\{)))
  3122. (message
  3123. "End of `%s%s%c ... %c' string/RE not found: %s"
  3124. argument
  3125. (if ostart (format "%c ... %c" ostart (or oend ostart)) "")
  3126. starter (or ender starter) bb)
  3127. (or (car err-l) (setcar err-l b)))))
  3128. (if set-st
  3129. (progn
  3130. (modify-syntax-entry starter (if (eq starter ?\\) "\\" ".") st)
  3131. (if ender (modify-syntax-entry ender "." st))))
  3132. ;; i: have 2 args, after end of the first arg
  3133. ;; i2: start of the second arg, if any (before delim if `ender').
  3134. ;; ender: the last arg bounded by parens-like chars, the second one of them
  3135. ;; starter: the starting delimiter of the first arg
  3136. ;; go-forward: has 2 args, and the second part is empty
  3137. (list i i2 ender starter go-forward)))
  3138. (defun cperl-forward-group-in-re (&optional st-l)
  3139. "Find the end of a group in a REx.
  3140. Return the error message (if any). Does not work if delimiter is `)'.
  3141. Works before syntax recognition is done."
  3142. ;; Works *before* syntax recognition is done
  3143. (or st-l (setq st-l (list nil))) ; Avoid overwriting '()
  3144. (let (st b reset-st)
  3145. (condition-case b
  3146. (progn
  3147. (setq st (cperl-cached-syntax-table st-l))
  3148. (modify-syntax-entry ?\( "()" st)
  3149. (modify-syntax-entry ?\) ")(" st)
  3150. (setq reset-st (syntax-table))
  3151. (set-syntax-table st)
  3152. (forward-sexp 1))
  3153. (error (message
  3154. "cperl-forward-group-in-re: error %s" b)))
  3155. ;; now restore the initial state
  3156. (if st
  3157. (progn
  3158. (modify-syntax-entry ?\( "." st)
  3159. (modify-syntax-entry ?\) "." st)))
  3160. (if reset-st
  3161. (set-syntax-table reset-st))
  3162. b))
  3163. (defvar font-lock-string-face)
  3164. ;;(defvar font-lock-reference-face)
  3165. (defvar font-lock-constant-face)
  3166. (defsubst cperl-postpone-fontification (b e type val &optional now)
  3167. ;; Do after syntactic fontification?
  3168. (if cperl-syntaxify-by-font-lock
  3169. (or now (put-text-property b e 'cperl-postpone (cons type val)))
  3170. (put-text-property b e type val)))
  3171. ;;; Here is how the global structures (those which cannot be
  3172. ;;; recognized locally) are marked:
  3173. ;; a) PODs:
  3174. ;; Start-to-end is marked `in-pod' ==> t
  3175. ;; Each non-literal part is marked `syntax-type' ==> `pod'
  3176. ;; Each literal part is marked `syntax-type' ==> `in-pod'
  3177. ;; b) HEREs:
  3178. ;; Start-to-end is marked `here-doc-group' ==> t
  3179. ;; The body is marked `syntax-type' ==> `here-doc'
  3180. ;; The delimiter is marked `syntax-type' ==> `here-doc-delim'
  3181. ;; c) FORMATs:
  3182. ;; First line (to =) marked `first-format-line' ==> t
  3183. ;; After-this--to-end is marked `syntax-type' ==> `format'
  3184. ;; d) 'Q'uoted string:
  3185. ;; part between markers inclusive is marked `syntax-type' ==> `string'
  3186. ;; part between `q' and the first marker is marked `syntax-type' ==> `prestring'
  3187. ;; second part of s///e is marked `syntax-type' ==> `multiline'
  3188. ;; e) Attributes of subroutines: `attrib-group' ==> t
  3189. ;; (or 0 if declaration); up to `{' or ';': `syntax-type' => `sub-decl'.
  3190. ;; f) Multiline my/our declaration lists etc: `syntax-type' => `multiline'
  3191. ;;; In addition, some parts of RExes may be marked as `REx-interpolated'
  3192. ;;; (value: 0 in //o, 1 if "interpolated variable" is whole-REx, t otherwise).
  3193. (defun cperl-unwind-to-safe (before &optional end)
  3194. ;; if BEFORE, go to the previous start-of-line on each step of unwinding
  3195. (let ((pos (point)) opos)
  3196. (while (and pos (progn
  3197. (beginning-of-line)
  3198. (get-text-property (setq pos (point)) 'syntax-type)))
  3199. (setq opos pos
  3200. pos (cperl-beginning-of-property pos 'syntax-type))
  3201. (if (eq pos (point-min))
  3202. (setq pos nil))
  3203. (if pos
  3204. (if before
  3205. (progn
  3206. (goto-char (cperl-1- pos))
  3207. (beginning-of-line)
  3208. (setq pos (point)))
  3209. (goto-char (setq pos (cperl-1- pos))))
  3210. ;; Up to the start
  3211. (goto-char (point-min))))
  3212. ;; Skip empty lines
  3213. (and (looking-at "\n*=")
  3214. (/= 0 (skip-chars-backward "\n"))
  3215. (forward-char))
  3216. (setq pos (point))
  3217. (if end
  3218. ;; Do the same for end, going small steps
  3219. (save-excursion
  3220. (while (and end (< end (point-max))
  3221. (get-text-property end 'syntax-type))
  3222. (setq pos end
  3223. end (next-single-property-change end 'syntax-type nil (point-max)))
  3224. (if end (progn (goto-char end)
  3225. (or (bolp) (forward-line 1))
  3226. (setq end (point)))))
  3227. (or end pos)))))
  3228. ;;; These are needed for byte-compile (at least with v19)
  3229. (defvar cperl-nonoverridable-face)
  3230. (defvar font-lock-variable-name-face)
  3231. (defvar font-lock-function-name-face)
  3232. (defvar font-lock-keyword-face)
  3233. (defvar font-lock-builtin-face)
  3234. (defvar font-lock-type-face)
  3235. (defvar font-lock-comment-face)
  3236. (defvar font-lock-warning-face)
  3237. (defun cperl-find-sub-attrs (&optional st-l b-fname e-fname pos)
  3238. "Syntactically mark (and fontify) attributes of a subroutine.
  3239. Should be called with the point before leading colon of an attribute."
  3240. ;; Works *before* syntax recognition is done
  3241. (or st-l (setq st-l (list nil))) ; Avoid overwriting '()
  3242. (let (st b p reset-st after-first (start (point)) start1 end1)
  3243. (condition-case b
  3244. (while (looking-at
  3245. (concat
  3246. "\\(" ; 1=optional? colon
  3247. ":" cperl-maybe-white-and-comment-rex ; 2=whitespace/comment?
  3248. "\\)"
  3249. (if after-first "?" "")
  3250. ;; No space between name and paren allowed...
  3251. "\\(\\sw+\\)" ; 3=name
  3252. "\\((\\)?")) ; 4=optional paren
  3253. (and (match-beginning 1)
  3254. (cperl-postpone-fontification
  3255. (match-beginning 0) (cperl-1+ (match-beginning 0))
  3256. 'face font-lock-constant-face))
  3257. (setq start1 (match-beginning 3) end1 (match-end 3))
  3258. (cperl-postpone-fontification start1 end1
  3259. 'face font-lock-constant-face)
  3260. (goto-char end1) ; end or before `('
  3261. (if (match-end 4) ; Have attribute arguments...
  3262. (progn
  3263. (if st nil
  3264. (setq st (cperl-cached-syntax-table st-l))
  3265. (modify-syntax-entry ?\( "()" st)
  3266. (modify-syntax-entry ?\) ")(" st))
  3267. (setq reset-st (syntax-table) p (point))
  3268. (set-syntax-table st)
  3269. (forward-sexp 1)
  3270. (set-syntax-table reset-st)
  3271. (setq reset-st nil)
  3272. (cperl-commentify p (point) t))) ; mark as string
  3273. (forward-comment (buffer-size))
  3274. (setq after-first t))
  3275. (error (message
  3276. "L%d: attribute `%s': %s"
  3277. (count-lines (point-min) (point))
  3278. (and start1 end1 (buffer-substring start1 end1)) b)
  3279. (setq start nil)))
  3280. (and start
  3281. (progn
  3282. (put-text-property start (point)
  3283. 'attrib-group (if (looking-at "{") t 0))
  3284. (and pos
  3285. (< 1 (count-lines (+ 3 pos) (point))) ; end of `sub'
  3286. ;; Apparently, we do not need `multiline': faces added now
  3287. (put-text-property (+ 3 pos) (cperl-1+ (point))
  3288. 'syntax-type 'sub-decl))
  3289. (and b-fname ; Fontify here: the following condition
  3290. (cperl-postpone-fontification ; is too hard to determine by
  3291. b-fname e-fname 'face ; a REx, so do it here
  3292. (if (looking-at "{")
  3293. font-lock-function-name-face
  3294. font-lock-variable-name-face)))))
  3295. ;; now restore the initial state
  3296. (if st
  3297. (progn
  3298. (modify-syntax-entry ?\( "." st)
  3299. (modify-syntax-entry ?\) "." st)))
  3300. (if reset-st
  3301. (set-syntax-table reset-st))))
  3302. (defsubst cperl-look-at-leading-count (is-x-REx e)
  3303. (if (and
  3304. (< (point) e)
  3305. (re-search-forward (concat "\\=" (if is-x-REx "[ \t\n]*" "") "[{?+*]")
  3306. (1- e) t)) ; return nil on failure, no moving
  3307. (if (eq ?\{ (preceding-char)) nil
  3308. (cperl-postpone-fontification
  3309. (1- (point)) (point)
  3310. 'face font-lock-warning-face))))
  3311. ;; Do some smarter-highlighting
  3312. ;; XXXX Currently ignores alphanum/dash delims,
  3313. (defsubst cperl-highlight-charclass (endbracket dashface bsface onec-space)
  3314. (let ((l '(1 5 7)) ll lle lll
  3315. ;; 2 groups, the first takes the whole match (include \[trnfabe])
  3316. (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{[^{}]*}" "\\)")))
  3317. (while ; look for unescaped - between non-classes
  3318. (re-search-forward
  3319. ;; On 19.33, certain simplifications lead
  3320. ;; to bugs (as in [^a-z] \\| [trnfabe] )
  3321. (concat ; 1: SingleChar (include \[trnfabe])
  3322. singleChar
  3323. ;;"\\(" "[^\\\\]" "\\|" "\\\\[^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{[^{}]*}" "\\)"
  3324. "\\(" ; 3: DASH SingleChar (match optionally)
  3325. "\\(-\\)" ; 4: DASH
  3326. singleChar ; 5: SingleChar
  3327. ;;"\\(" "[^\\\\]" "\\|" "\\\\[^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{[^{}]*}" "\\)"
  3328. "\\)?"
  3329. "\\|"
  3330. "\\(" ; 7: other escapes
  3331. "\\\\[pP]" "\\([^{]\\|{[^{}]*}\\)"
  3332. "\\|" "\\\\[^pP]" "\\)"
  3333. )
  3334. endbracket 'toend)
  3335. (if (match-beginning 4)
  3336. (cperl-postpone-fontification
  3337. (match-beginning 4) (match-end 4)
  3338. 'face dashface))
  3339. ;; save match data (for looking-at)
  3340. (setq lll (mapcar (function (lambda (elt) (cons (match-beginning elt)
  3341. (match-end elt)))) l))
  3342. (while lll
  3343. (setq ll (car lll))
  3344. (setq lle (cdr ll)
  3345. ll (car ll))
  3346. ;; (message "Got %s of %s" ll l)
  3347. (if (and ll (eq (char-after ll) ?\\ ))
  3348. (save-excursion
  3349. (goto-char ll)
  3350. (cperl-postpone-fontification ll (1+ ll)
  3351. 'face bsface)
  3352. (if (looking-at "\\\\[a-zA-Z0-9]")
  3353. (cperl-postpone-fontification (1+ ll) lle
  3354. 'face onec-space))))
  3355. (setq lll (cdr lll))))
  3356. (goto-char endbracket) ; just in case something misbehaves???
  3357. t))
  3358. ;;; Debugging this may require (setq max-specpdl-size 2000)...
  3359. (defun cperl-find-pods-heres (&optional min max non-inter end ignore-max end-of-here-doc)
  3360. "Scans the buffer for hard-to-parse Perl constructions.
  3361. If `cperl-pod-here-fontify' is not-nil after evaluation, will fontify
  3362. the sections using `cperl-pod-head-face', `cperl-pod-face',
  3363. `cperl-here-face'."
  3364. (interactive)
  3365. (or min (setq min (point-min)
  3366. cperl-syntax-state nil
  3367. cperl-syntax-done-to min))
  3368. (or max (setq max (point-max)))
  3369. (let* ((cperl-pod-here-fontify (eval cperl-pod-here-fontify)) go tmpend
  3370. face head-face here-face b e bb tag qtag b1 e1 argument i c tail tb
  3371. is-REx is-x-REx REx-subgr-start REx-subgr-end was-subgr i2 hairy-RE
  3372. (case-fold-search nil) (inhibit-read-only t) (buffer-undo-list t)
  3373. (modified (buffer-modified-p)) overshoot is-o-REx name
  3374. (inhibit-modification-hooks t)
  3375. (cperl-font-locking t)
  3376. (use-syntax-state (and cperl-syntax-state
  3377. (>= min (car cperl-syntax-state))))
  3378. (state-point (if use-syntax-state
  3379. (car cperl-syntax-state)
  3380. (point-min)))
  3381. (state (if use-syntax-state
  3382. (cdr cperl-syntax-state)))
  3383. ;; (st-l '(nil)) (err-l '(nil)) ; Would overwrite - propagates from a function call to a function call!
  3384. (st-l (list nil)) (err-l (list nil))
  3385. ;; Somehow font-lock may be not loaded yet...
  3386. ;; (e.g., when building TAGS via command-line call)
  3387. (font-lock-string-face (if (boundp 'font-lock-string-face)
  3388. font-lock-string-face
  3389. 'font-lock-string-face))
  3390. (my-cperl-delimiters-face (if (boundp 'font-lock-constant-face)
  3391. font-lock-constant-face
  3392. 'font-lock-constant-face))
  3393. (my-cperl-REx-spec-char-face ; [] ^.$ and wrapper-of ({})
  3394. (if (boundp 'font-lock-function-name-face)
  3395. font-lock-function-name-face
  3396. 'font-lock-function-name-face))
  3397. (font-lock-variable-name-face ; interpolated vars and ({})-code
  3398. (if (boundp 'font-lock-variable-name-face)
  3399. font-lock-variable-name-face
  3400. 'font-lock-variable-name-face))
  3401. (font-lock-function-name-face ; used in `cperl-find-sub-attrs'
  3402. (if (boundp 'font-lock-function-name-face)
  3403. font-lock-function-name-face
  3404. 'font-lock-function-name-face))
  3405. (font-lock-constant-face ; used in `cperl-find-sub-attrs'
  3406. (if (boundp 'font-lock-constant-face)
  3407. font-lock-constant-face
  3408. 'font-lock-constant-face))
  3409. (my-cperl-REx-0length-face ; 0-length, (?:)etc, non-literal \
  3410. (if (boundp 'font-lock-builtin-face)
  3411. font-lock-builtin-face
  3412. 'font-lock-builtin-face))
  3413. (font-lock-comment-face
  3414. (if (boundp 'font-lock-comment-face)
  3415. font-lock-comment-face
  3416. 'font-lock-comment-face))
  3417. (font-lock-warning-face
  3418. (if (boundp 'font-lock-warning-face)
  3419. font-lock-warning-face
  3420. 'font-lock-warning-face))
  3421. (my-cperl-REx-ctl-face ; (|)
  3422. (if (boundp 'font-lock-keyword-face)
  3423. font-lock-keyword-face
  3424. 'font-lock-keyword-face))
  3425. (my-cperl-REx-modifiers-face ; //gims
  3426. (if (boundp 'cperl-nonoverridable-face)
  3427. cperl-nonoverridable-face
  3428. 'cperl-nonoverridable-face))
  3429. (my-cperl-REx-length1-face ; length=1 escaped chars, POSIX classes
  3430. (if (boundp 'font-lock-type-face)
  3431. font-lock-type-face
  3432. 'font-lock-type-face))
  3433. (stop-point (if ignore-max
  3434. (point-max)
  3435. max))
  3436. (search
  3437. (concat
  3438. "\\(\\`\n?\\|^\n\\)=" ; POD
  3439. "\\|"
  3440. ;; One extra () before this:
  3441. "<<" ; HERE-DOC
  3442. "\\(" ; 1 + 1
  3443. ;; First variant "BLAH" or just ``.
  3444. "[ \t]*" ; Yes, whitespace is allowed!
  3445. "\\([\"'`]\\)" ; 2 + 1 = 3
  3446. "\\([^\"'`\n]*\\)" ; 3 + 1
  3447. "\\3"
  3448. "\\|"
  3449. ;; Second variant: Identifier or \ID (same as 'ID') or empty
  3450. "\\\\?\\(\\([a-zA-Z_][a-zA-Z_0-9]*\\)?\\)" ; 4 + 1, 5 + 1
  3451. ;; Do not have <<= or << 30 or <<30 or << $blah.
  3452. ;; "\\([^= \t0-9$@%&]\\|[ \t]+[^ \t\n0-9$@%&]\\)" ; 6 + 1
  3453. "\\(\\)" ; To preserve count of pars :-( 6 + 1
  3454. "\\)"
  3455. "\\|"
  3456. ;; 1+6 extra () before this:
  3457. "^[ \t]*\\(format\\)[ \t]*\\([a-zA-Z0-9_]+\\)?[ \t]*=[ \t]*$" ;FRMAT
  3458. (if cperl-use-syntax-table-text-property
  3459. (concat
  3460. "\\|"
  3461. ;; 1+6+2=9 extra () before this:
  3462. "\\<\\(q[wxqr]?\\|[msy]\\|tr\\)\\>" ; QUOTED CONSTRUCT
  3463. "\\|"
  3464. ;; 1+6+2+1=10 extra () before this:
  3465. "\\([?/<]\\)" ; /blah/ or ?blah? or <file*glob>
  3466. "\\|"
  3467. ;; 1+6+2+1+1=11 extra () before this
  3468. "\\<sub\\>" ; sub with proto/attr
  3469. "\\("
  3470. cperl-white-and-comment-rex
  3471. "\\(::[a-zA-Z_:'0-9]*\\|[a-zA-Z_'][a-zA-Z_:'0-9]*\\)\\)?" ; name
  3472. "\\("
  3473. cperl-maybe-white-and-comment-rex
  3474. "\\(([^()]*)\\|:[^:]\\)\\)" ; prototype or attribute start
  3475. "\\|"
  3476. ;; 1+6+2+1+1+6=17 extra () before this:
  3477. "\\$\\(['{]\\)" ; $' or ${foo}
  3478. "\\|"
  3479. ;; 1+6+2+1+1+6+1=18 extra () before this (old pack'var syntax;
  3480. ;; we do not support intervening comments...):
  3481. "\\(\\<sub[ \t\n\f]+\\|[&*$@%]\\)[a-zA-Z0-9_]*'"
  3482. ;; 1+6+2+1+1+6+1+1=19 extra () before this:
  3483. "\\|"
  3484. "__\\(END\\|DATA\\)__" ; __END__ or __DATA__
  3485. ;; 1+6+2+1+1+6+1+1+1=20 extra () before this:
  3486. "\\|"
  3487. "\\\\\\(['`\"($]\\)") ; BACKWACKED something-hairy
  3488. ""))))
  3489. (unwind-protect
  3490. (progn
  3491. (save-excursion
  3492. (or non-inter
  3493. (message "Scanning for \"hard\" Perl constructions..."))
  3494. ;;(message "find: %s --> %s" min max)
  3495. (and cperl-pod-here-fontify
  3496. ;; We had evals here, do not know why...
  3497. (setq face cperl-pod-face
  3498. head-face cperl-pod-head-face
  3499. here-face cperl-here-face))
  3500. (remove-text-properties min max
  3501. '(syntax-type t in-pod t syntax-table t
  3502. attrib-group t
  3503. REx-interpolated t
  3504. cperl-postpone t
  3505. syntax-subtype t
  3506. rear-nonsticky t
  3507. front-sticky t
  3508. here-doc-group t
  3509. first-format-line t
  3510. REx-part2 t
  3511. indentable t))
  3512. ;; Need to remove face as well...
  3513. (goto-char min)
  3514. ;; 'emx not supported by Emacs since at least 21.1.
  3515. (and (featurep 'xemacs) (eq system-type 'emx)
  3516. (eq (point) 1)
  3517. (let ((case-fold-search t))
  3518. (looking-at "extproc[ \t]")) ; Analogue of #!
  3519. (cperl-commentify min
  3520. (point-at-eol)
  3521. nil))
  3522. (while (and
  3523. (< (point) max)
  3524. (re-search-forward search max t))
  3525. (setq tmpend nil) ; Valid for most cases
  3526. (setq b (match-beginning 0)
  3527. state (save-excursion (parse-partial-sexp
  3528. state-point b nil nil state))
  3529. state-point b)
  3530. (cond
  3531. ;; 1+6+2+1+1+6=17 extra () before this:
  3532. ;; "\\$\\(['{]\\)"
  3533. ((match-beginning 18) ; $' or ${foo}
  3534. (if (eq (preceding-char) ?\') ; $'
  3535. (progn
  3536. (setq b (1- (point))
  3537. state (parse-partial-sexp
  3538. state-point (1- b) nil nil state)
  3539. state-point (1- b))
  3540. (if (nth 3 state) ; in string
  3541. (cperl-modify-syntax-type (1- b) cperl-st-punct))
  3542. (goto-char (1+ b)))
  3543. ;; else: ${
  3544. (setq bb (match-beginning 0))
  3545. (cperl-modify-syntax-type bb cperl-st-punct)))
  3546. ;; No processing in strings/comments beyond this point:
  3547. ((or (nth 3 state) (nth 4 state))
  3548. t) ; Do nothing in comment/string
  3549. ((match-beginning 1) ; POD section
  3550. ;; "\\(\\`\n?\\|^\n\\)="
  3551. (setq b (match-beginning 0)
  3552. state (parse-partial-sexp
  3553. state-point b nil nil state)
  3554. state-point b)
  3555. (if (or (nth 3 state) (nth 4 state)
  3556. (looking-at "cut\\>"))
  3557. (if (or (nth 3 state) (nth 4 state) ignore-max)
  3558. nil ; Doing a chunk only
  3559. (message "=cut is not preceded by a POD section")
  3560. (or (car err-l) (setcar err-l (point))))
  3561. (beginning-of-line)
  3562. (setq b (point)
  3563. bb b
  3564. tb (match-beginning 0)
  3565. b1 nil) ; error condition
  3566. ;; We do not search to max, since we may be called from
  3567. ;; some hook of fontification, and max is random
  3568. (or (re-search-forward "^\n=cut\\>" stop-point 'toend)
  3569. (progn
  3570. (goto-char b)
  3571. (if (re-search-forward "\n=cut\\>" stop-point 'toend)
  3572. (progn
  3573. (message "=cut is not preceded by an empty line")
  3574. (setq b1 t)
  3575. (or (car err-l) (setcar err-l b))))))
  3576. (beginning-of-line 2) ; An empty line after =cut is not POD!
  3577. (setq e (point))
  3578. (and (> e max)
  3579. (progn
  3580. (remove-text-properties
  3581. max e '(syntax-type t in-pod t syntax-table t
  3582. attrib-group t
  3583. REx-interpolated t
  3584. cperl-postpone t
  3585. syntax-subtype t
  3586. here-doc-group t
  3587. rear-nonsticky t
  3588. front-sticky t
  3589. first-format-line t
  3590. REx-part2 t
  3591. indentable t))
  3592. (setq tmpend tb)))
  3593. (put-text-property b e 'in-pod t)
  3594. (put-text-property b e 'syntax-type 'in-pod)
  3595. (goto-char b)
  3596. (while (re-search-forward "\n\n[ \t]" e t)
  3597. ;; We start 'pod 1 char earlier to include the preceding line
  3598. (beginning-of-line)
  3599. (put-text-property (cperl-1- b) (point) 'syntax-type 'pod)
  3600. (cperl-put-do-not-fontify b (point) t)
  3601. ;; mark the non-literal parts as PODs
  3602. (if cperl-pod-here-fontify
  3603. (cperl-postpone-fontification b (point) 'face face t))
  3604. (re-search-forward "\n\n[^ \t\f\n]" e 'toend)
  3605. (beginning-of-line)
  3606. (setq b (point)))
  3607. (put-text-property (cperl-1- (point)) e 'syntax-type 'pod)
  3608. (cperl-put-do-not-fontify (point) e t)
  3609. (if cperl-pod-here-fontify
  3610. (progn
  3611. ;; mark the non-literal parts as PODs
  3612. (cperl-postpone-fontification (point) e 'face face t)
  3613. (goto-char bb)
  3614. (if (looking-at
  3615. "=[a-zA-Z0-9_]+\\>[ \t]*\\(\\(\n?[^\n]\\)+\\)$")
  3616. ;; mark the headers
  3617. (cperl-postpone-fontification
  3618. (match-beginning 1) (match-end 1)
  3619. 'face head-face))
  3620. (while (re-search-forward
  3621. ;; One paragraph
  3622. "^\n=[a-zA-Z0-9_]+\\>[ \t]*\\(\\(\n?[^\n]\\)+\\)$"
  3623. e 'toend)
  3624. ;; mark the headers
  3625. (cperl-postpone-fontification
  3626. (match-beginning 1) (match-end 1)
  3627. 'face head-face))))
  3628. (cperl-commentify bb e nil)
  3629. (goto-char e)
  3630. (or (eq e (point-max))
  3631. (forward-char -1)))) ; Prepare for immediate POD start.
  3632. ;; Here document
  3633. ;; We can do many here-per-line;
  3634. ;; but multiline quote on the same line as <<HERE confuses us...
  3635. ;; ;; One extra () before this:
  3636. ;;"<<"
  3637. ;; "\\(" ; 1 + 1
  3638. ;; ;; First variant "BLAH" or just ``.
  3639. ;; "[ \t]*" ; Yes, whitespace is allowed!
  3640. ;; "\\([\"'`]\\)" ; 2 + 1
  3641. ;; "\\([^\"'`\n]*\\)" ; 3 + 1
  3642. ;; "\\3"
  3643. ;; "\\|"
  3644. ;; ;; Second variant: Identifier or \ID or empty
  3645. ;; "\\\\?\\(\\([a-zA-Z_][a-zA-Z_0-9]*\\)?\\)" ; 4 + 1, 5 + 1
  3646. ;; ;; Do not have <<= or << 30 or <<30 or << $blah.
  3647. ;; ;; "\\([^= \t0-9$@%&]\\|[ \t]+[^ \t\n0-9$@%&]\\)" ; 6 + 1
  3648. ;; "\\(\\)" ; To preserve count of pars :-( 6 + 1
  3649. ;; "\\)"
  3650. ((match-beginning 2) ; 1 + 1
  3651. (setq b (point)
  3652. tb (match-beginning 0)
  3653. c (and ; not HERE-DOC
  3654. (match-beginning 5)
  3655. (save-match-data
  3656. (or (looking-at "[ \t]*(") ; << function_call()
  3657. (save-excursion ; 1 << func_name, or $foo << 10
  3658. (condition-case nil
  3659. (progn
  3660. (goto-char tb)
  3661. ;;; XXX What to do: foo <<bar ???
  3662. ;;; XXX Need to support print {a} <<B ???
  3663. (forward-sexp -1)
  3664. (save-match-data
  3665. ; $foo << b; $f .= <<B;
  3666. ; ($f+1) << b; a($f) . <<B;
  3667. ; foo 1, <<B; $x{a} <<b;
  3668. (cond
  3669. ((looking-at "[0-9$({]")
  3670. (forward-sexp 1)
  3671. (and
  3672. (looking-at "[ \t]*<<")
  3673. (condition-case nil
  3674. ;; print $foo <<EOF
  3675. (progn
  3676. (forward-sexp -2)
  3677. (not
  3678. (looking-at "\\(printf?\\|system\\|exec\\|sort\\)\\>")))
  3679. (error t)))))))
  3680. (error nil))) ; func(<<EOF)
  3681. (and (not (match-beginning 6)) ; Empty
  3682. (looking-at
  3683. "[ \t]*[=0-9$@%&(]"))))))
  3684. (if c ; Not here-doc
  3685. nil ; Skip it.
  3686. (setq c (match-end 2)) ; 1 + 1
  3687. (if (match-beginning 5) ;4 + 1
  3688. (setq b1 (match-beginning 5) ; 4 + 1
  3689. e1 (match-end 5)) ; 4 + 1
  3690. (setq b1 (match-beginning 4) ; 3 + 1
  3691. e1 (match-end 4))) ; 3 + 1
  3692. (setq tag (buffer-substring b1 e1)
  3693. qtag (regexp-quote tag))
  3694. (cond (cperl-pod-here-fontify
  3695. ;; Highlight the starting delimiter
  3696. (cperl-postpone-fontification
  3697. b1 e1 'face my-cperl-delimiters-face)
  3698. (cperl-put-do-not-fontify b1 e1 t)))
  3699. (forward-line)
  3700. (setq i (point))
  3701. (if end-of-here-doc
  3702. (goto-char end-of-here-doc))
  3703. (setq b (point))
  3704. ;; We do not search to max, since we may be called from
  3705. ;; some hook of fontification, and max is random
  3706. (or (and (re-search-forward (concat "^" qtag "$")
  3707. stop-point 'toend)
  3708. ;;;(eq (following-char) ?\n) ; XXXX WHY???
  3709. )
  3710. (progn ; Pretend we matched at the end
  3711. (goto-char (point-max))
  3712. (re-search-forward "\\'")
  3713. (message "End of here-document `%s' not found." tag)
  3714. (or (car err-l) (setcar err-l b))))
  3715. (if cperl-pod-here-fontify
  3716. (progn
  3717. ;; Highlight the ending delimiter
  3718. (cperl-postpone-fontification
  3719. (match-beginning 0) (match-end 0)
  3720. 'face my-cperl-delimiters-face)
  3721. (cperl-put-do-not-fontify b (match-end 0) t)
  3722. ;; Highlight the HERE-DOC
  3723. (cperl-postpone-fontification b (match-beginning 0)
  3724. 'face here-face)))
  3725. (setq e1 (cperl-1+ (match-end 0)))
  3726. (put-text-property b (match-beginning 0)
  3727. 'syntax-type 'here-doc)
  3728. (put-text-property (match-beginning 0) e1
  3729. 'syntax-type 'here-doc-delim)
  3730. (put-text-property b e1 'here-doc-group t)
  3731. ;; This makes insertion at the start of HERE-DOC update
  3732. ;; the whole construct:
  3733. (put-text-property b (cperl-1+ b) 'front-sticky '(syntax-type))
  3734. (cperl-commentify b e1 nil)
  3735. (cperl-put-do-not-fontify b (match-end 0) t)
  3736. ;; Cache the syntax info...
  3737. (setq cperl-syntax-state (cons state-point state))
  3738. ;; ... and process the rest of the line...
  3739. (setq overshoot
  3740. (elt ; non-inter ignore-max
  3741. (cperl-find-pods-heres c i t end t e1) 1))
  3742. (if (and overshoot (> overshoot (point)))
  3743. (goto-char overshoot)
  3744. (setq overshoot e1))
  3745. (if (> e1 max)
  3746. (setq tmpend tb))))
  3747. ;; format
  3748. ((match-beginning 8)
  3749. ;; 1+6=7 extra () before this:
  3750. ;;"^[ \t]*\\(format\\)[ \t]*\\([a-zA-Z0-9_]+\\)?[ \t]*=[ \t]*$"
  3751. (setq b (point)
  3752. name (if (match-beginning 8) ; 7 + 1
  3753. (buffer-substring (match-beginning 8) ; 7 + 1
  3754. (match-end 8)) ; 7 + 1
  3755. "")
  3756. tb (match-beginning 0))
  3757. (setq argument nil)
  3758. (put-text-property (point-at-bol) b 'first-format-line 't)
  3759. (if cperl-pod-here-fontify
  3760. (while (and (eq (forward-line) 0)
  3761. (not (looking-at "^[.;]$")))
  3762. (cond
  3763. ((looking-at "^#")) ; Skip comments
  3764. ((and argument ; Skip argument multi-lines
  3765. (looking-at "^[ \t]*{"))
  3766. (forward-sexp 1)
  3767. (setq argument nil))
  3768. (argument ; Skip argument lines
  3769. (setq argument nil))
  3770. (t ; Format line
  3771. (setq b1 (point))
  3772. (setq argument (looking-at "^[^\n]*[@^]"))
  3773. (end-of-line)
  3774. ;; Highlight the format line
  3775. (cperl-postpone-fontification b1 (point)
  3776. 'face font-lock-string-face)
  3777. (cperl-commentify b1 (point) nil)
  3778. (cperl-put-do-not-fontify b1 (point) t))))
  3779. ;; We do not search to max, since we may be called from
  3780. ;; some hook of fontification, and max is random
  3781. (re-search-forward "^[.;]$" stop-point 'toend))
  3782. (beginning-of-line)
  3783. (if (looking-at "^\\.$") ; ";" is not supported yet
  3784. (progn
  3785. ;; Highlight the ending delimiter
  3786. (cperl-postpone-fontification (point) (+ (point) 2)
  3787. 'face font-lock-string-face)
  3788. (cperl-commentify (point) (+ (point) 2) nil)
  3789. (cperl-put-do-not-fontify (point) (+ (point) 2) t))
  3790. (message "End of format `%s' not found." name)
  3791. (or (car err-l) (setcar err-l b)))
  3792. (forward-line)
  3793. (if (> (point) max)
  3794. (setq tmpend tb))
  3795. (put-text-property b (point) 'syntax-type 'format))
  3796. ;; qq-like String or Regexp:
  3797. ((or (match-beginning 10) (match-beginning 11))
  3798. ;; 1+6+2=9 extra () before this:
  3799. ;; "\\<\\(q[wxqr]?\\|[msy]\\|tr\\)\\>"
  3800. ;; "\\|"
  3801. ;; "\\([?/<]\\)" ; /blah/ or ?blah? or <file*glob>
  3802. (setq b1 (if (match-beginning 10) 10 11)
  3803. argument (buffer-substring
  3804. (match-beginning b1) (match-end b1))
  3805. b (point) ; end of qq etc
  3806. i b
  3807. c (char-after (match-beginning b1))
  3808. bb (char-after (1- (match-beginning b1))) ; tmp holder
  3809. ;; bb == "Not a stringy"
  3810. bb (if (eq b1 10) ; user variables/whatever
  3811. (and (memq bb (append "$@%*#_:-&>" nil)) ; $#y)
  3812. (cond ((eq bb ?-) (eq c ?s)) ; -s file test
  3813. ((eq bb ?\:) ; $opt::s
  3814. (eq (char-after
  3815. (- (match-beginning b1) 2))
  3816. ?\:))
  3817. ((eq bb ?\>) ; $foo->s
  3818. (eq (char-after
  3819. (- (match-beginning b1) 2))
  3820. ?\-))
  3821. ((eq bb ?\&)
  3822. (not (eq (char-after ; &&m/blah/
  3823. (- (match-beginning b1) 2))
  3824. ?\&)))
  3825. (t t)))
  3826. ;; <file> or <$file>
  3827. (and (eq c ?\<)
  3828. ;; Do not stringify <FH>, <$fh> :
  3829. (save-match-data
  3830. (looking-at
  3831. "\\$?\\([_a-zA-Z:][_a-zA-Z0-9:]*\\)?>"))))
  3832. tb (match-beginning 0))
  3833. (goto-char (match-beginning b1))
  3834. (cperl-backward-to-noncomment (point-min))
  3835. (or bb
  3836. (if (eq b1 11) ; bare /blah/ or ?blah? or <foo>
  3837. (setq argument ""
  3838. b1 nil
  3839. bb ; Not a regexp?
  3840. (not
  3841. ;; What is below: regexp-p?
  3842. (and
  3843. (or (memq (preceding-char)
  3844. (append (if (memq c '(?\? ?\<))
  3845. ;; $a++ ? 1 : 2
  3846. "~{(=|&*!,;:["
  3847. "~{(=|&+-*!,;:[") nil))
  3848. (and (eq (preceding-char) ?\})
  3849. (cperl-after-block-p (point-min)))
  3850. (and (eq (char-syntax (preceding-char)) ?w)
  3851. (progn
  3852. (forward-sexp -1)
  3853. ;; After these keywords `/' starts a RE. One should add all the
  3854. ;; functions/builtins which expect an argument, but ...
  3855. (if (eq (preceding-char) ?-)
  3856. ;; -d ?foo? is a RE
  3857. (looking-at "[a-zA-Z]\\>")
  3858. (and
  3859. (not (memq (preceding-char)
  3860. '(?$ ?@ ?& ?%)))
  3861. (looking-at
  3862. "\\(while\\|if\\|unless\\|until\\|and\\|or\\|not\\|xor\\|split\\|grep\\|map\\|print\\)\\>")))))
  3863. (and (eq (preceding-char) ?.)
  3864. (eq (char-after (- (point) 2)) ?.))
  3865. (bobp))
  3866. ;; m|blah| ? foo : bar;
  3867. (not
  3868. (and (eq c ?\?)
  3869. cperl-use-syntax-table-text-property
  3870. (not (bobp))
  3871. (progn
  3872. (forward-char -1)
  3873. (looking-at "\\s|"))))))
  3874. b (1- b))
  3875. ;; s y tr m
  3876. ;; Check for $a -> y
  3877. (setq b1 (preceding-char)
  3878. go (point))
  3879. (if (and (eq b1 ?>)
  3880. (eq (char-after (- go 2)) ?-))
  3881. ;; Not a regexp
  3882. (setq bb t))))
  3883. (or bb
  3884. (progn
  3885. (goto-char b)
  3886. (if (looking-at "[ \t\n\f]+\\(#[^\n]*\n[ \t\n\f]*\\)+")
  3887. (goto-char (match-end 0))
  3888. (skip-chars-forward " \t\n\f"))
  3889. (cond ((and (eq (following-char) ?\})
  3890. (eq b1 ?\{))
  3891. ;; Check for $a[23]->{ s }, @{s} and *{s::foo}
  3892. (goto-char (1- go))
  3893. (skip-chars-backward " \t\n\f")
  3894. (if (memq (preceding-char) (append "$@%&*" nil))
  3895. (setq bb t) ; @{y}
  3896. (condition-case nil
  3897. (forward-sexp -1)
  3898. (error nil)))
  3899. (if (or bb
  3900. (looking-at ; $foo -> {s}
  3901. "[$@]\\$*\\([a-zA-Z0-9_:]+\\|[^{]\\)\\([ \t\n]*->\\)?[ \t\n]*{")
  3902. (and ; $foo[12] -> {s}
  3903. (memq (following-char) '(?\{ ?\[))
  3904. (progn
  3905. (forward-sexp 1)
  3906. (looking-at "\\([ \t\n]*->\\)?[ \t\n]*{"))))
  3907. (setq bb t)
  3908. (goto-char b)))
  3909. ((and (eq (following-char) ?=)
  3910. (eq (char-after (1+ (point))) ?\>))
  3911. ;; Check for { foo => 1, s => 2 }
  3912. ;; Apparently s=> is never a substitution...
  3913. (setq bb t))
  3914. ((and (eq (following-char) ?:)
  3915. (eq b1 ?\{) ; Check for $ { s::bar }
  3916. (looking-at "::[a-zA-Z0-9_:]*[ \t\n\f]*}")
  3917. (progn
  3918. (goto-char (1- go))
  3919. (skip-chars-backward " \t\n\f")
  3920. (memq (preceding-char)
  3921. (append "$@%&*" nil))))
  3922. (setq bb t))
  3923. ((eobp)
  3924. (setq bb t)))))
  3925. (if bb
  3926. (goto-char i)
  3927. ;; Skip whitespace and comments...
  3928. (if (looking-at "[ \t\n\f]+\\(#[^\n]*\n[ \t\n\f]*\\)+")
  3929. (goto-char (match-end 0))
  3930. (skip-chars-forward " \t\n\f"))
  3931. (if (> (point) b)
  3932. (put-text-property b (point) 'syntax-type 'prestring))
  3933. ;; qtag means two-arg matcher, may be reset to
  3934. ;; 2 or 3 later if some special quoting is needed.
  3935. ;; e1 means matching-char matcher.
  3936. (setq b (point) ; before the first delimiter
  3937. ;; has 2 args
  3938. i2 (string-match "^\\([sy]\\|tr\\)$" argument)
  3939. ;; We do not search to max, since we may be called from
  3940. ;; some hook of fontification, and max is random
  3941. i (cperl-forward-re stop-point end
  3942. i2
  3943. st-l err-l argument)
  3944. ;; If `go', then it is considered as 1-arg, `b1' is nil
  3945. ;; as in s/foo//x; the point is before final "slash"
  3946. b1 (nth 1 i) ; start of the second part
  3947. tag (nth 2 i) ; ender-char, true if second part
  3948. ; is with matching chars []
  3949. go (nth 4 i) ; There is a 1-char part after the end
  3950. i (car i) ; intermediate point
  3951. e1 (point) ; end
  3952. ;; Before end of the second part if non-matching: ///
  3953. tail (if (and i (not tag))
  3954. (1- e1))
  3955. e (if i i e1) ; end of the first part
  3956. qtag nil ; need to preserve backslashitis
  3957. is-x-REx nil is-o-REx nil); REx has //x //o modifiers
  3958. ;; If s{} (), then b/b1 are at "{", "(", e1/i after ")", "}"
  3959. ;; Commenting \\ is dangerous, what about ( ?
  3960. (and i tail
  3961. (eq (char-after i) ?\\)
  3962. (setq qtag t))
  3963. (and (if go (looking-at ".\\sw*x")
  3964. (looking-at "\\sw*x")) ; qr//x
  3965. (setq is-x-REx t))
  3966. (and (if go (looking-at ".\\sw*o")
  3967. (looking-at "\\sw*o")) ; //o
  3968. (setq is-o-REx t))
  3969. (if (null i)
  3970. ;; Considered as 1arg form
  3971. (progn
  3972. (cperl-commentify b (point) t)
  3973. (put-text-property b (point) 'syntax-type 'string)
  3974. (if (or is-x-REx
  3975. ;; ignore other text properties:
  3976. (string-match "^qw$" argument))
  3977. (put-text-property b (point) 'indentable t))
  3978. (and go
  3979. (setq e1 (cperl-1+ e1))
  3980. (or (eobp)
  3981. (forward-char 1))))
  3982. (cperl-commentify b i t)
  3983. (if (looking-at "\\sw*e") ; s///e
  3984. (progn
  3985. ;; Cache the syntax info...
  3986. (setq cperl-syntax-state (cons state-point state))
  3987. (and
  3988. ;; silent:
  3989. (car (cperl-find-pods-heres b1 (1- (point)) t end))
  3990. ;; Error
  3991. (goto-char (1+ max)))
  3992. (if (and tag (eq (preceding-char) ?\>))
  3993. (progn
  3994. (cperl-modify-syntax-type (1- (point)) cperl-st-ket)
  3995. (cperl-modify-syntax-type i cperl-st-bra)))
  3996. (put-text-property b i 'syntax-type 'string)
  3997. (put-text-property i (point) 'syntax-type 'multiline)
  3998. (if is-x-REx
  3999. (put-text-property b i 'indentable t)))
  4000. (cperl-commentify b1 (point) t)
  4001. (put-text-property b (point) 'syntax-type 'string)
  4002. (if is-x-REx
  4003. (put-text-property b i 'indentable t))
  4004. (if qtag
  4005. (cperl-modify-syntax-type (1+ i) cperl-st-punct))
  4006. (setq tail nil)))
  4007. ;; Now: tail: if the second part is non-matching without ///e
  4008. (if (eq (char-syntax (following-char)) ?w)
  4009. (progn
  4010. (forward-word 1) ; skip modifiers s///s
  4011. (if tail (cperl-commentify tail (point) t))
  4012. (cperl-postpone-fontification
  4013. e1 (point) 'face my-cperl-REx-modifiers-face)))
  4014. ;; Check whether it is m// which means "previous match"
  4015. ;; and highlight differently
  4016. (setq is-REx
  4017. (and (string-match "^\\([sm]?\\|qr\\)$" argument)
  4018. (or (not (= (length argument) 0))
  4019. (not (eq c ?\<)))))
  4020. (if (and is-REx
  4021. (eq e (+ 2 b))
  4022. ;; split // *is* using zero-pattern
  4023. (save-excursion
  4024. (condition-case nil
  4025. (progn
  4026. (goto-char tb)
  4027. (forward-sexp -1)
  4028. (not (looking-at "split\\>")))
  4029. (error t))))
  4030. (cperl-postpone-fontification
  4031. b e 'face font-lock-warning-face)
  4032. (if (or i2 ; Has 2 args
  4033. (and cperl-fontify-m-as-s
  4034. (or
  4035. (string-match "^\\(m\\|qr\\)$" argument)
  4036. (and (eq 0 (length argument))
  4037. (not (eq ?\< (char-after b)))))))
  4038. (progn
  4039. (cperl-postpone-fontification
  4040. b (cperl-1+ b) 'face my-cperl-delimiters-face)
  4041. (cperl-postpone-fontification
  4042. (1- e) e 'face my-cperl-delimiters-face)))
  4043. (if (and is-REx cperl-regexp-scan)
  4044. ;; Process RExen: embedded comments, charclasses and ]
  4045. ;;;/\3333\xFg\x{FFF}a\ppp\PPP\qqq\C\99f(?{ foo })(??{ foo })/;
  4046. ;;;/a\.b[^a[:ff:]b]x$ab->$[|$,$ab->[cd]->[ef]|$ab[xy].|^${a,b}{c,d}/;
  4047. ;;;/(?<=foo)(?<!bar)(x)(?:$ab|\$\/)$|\\\b\x888\776\[\:$/xxx;
  4048. ;;;m?(\?\?{b,a})? + m/(??{aa})(?(?=xx)aa|bb)(?#aac)/;
  4049. ;;;m$(^ab[c]\$)$ + m+(^ab[c]\$\+)+ + m](^ab[c\]$|.+)] + m)(^ab[c]$|.+\));
  4050. ;;;m^a[\^b]c^ + m.a[^b]\.c.;
  4051. (save-excursion
  4052. (goto-char (1+ b))
  4053. ;; First
  4054. (cperl-look-at-leading-count is-x-REx e)
  4055. (setq hairy-RE
  4056. (concat
  4057. (if is-x-REx
  4058. (if (eq (char-after b) ?\#)
  4059. "\\((\\?\\\\#\\)\\|\\(\\\\#\\)"
  4060. "\\((\\?#\\)\\|\\(#\\)")
  4061. ;; keep the same count: add a fake group
  4062. (if (eq (char-after b) ?\#)
  4063. "\\((\\?\\\\#\\)\\(\\)"
  4064. "\\((\\?#\\)\\(\\)"))
  4065. "\\|"
  4066. "\\(\\[\\)" ; 3=[
  4067. "\\|"
  4068. "\\(]\\)" ; 4=]
  4069. "\\|"
  4070. ;; XXXX Will not be able to use it in s)))
  4071. (if (eq (char-after b) ?\) )
  4072. "\\())))\\)" ; Will never match
  4073. (if (eq (char-after b) ?? )
  4074. ;;"\\((\\\\\\?\\(\\\\\\?\\)?{\\)"
  4075. "\\((\\\\\\?\\\\\\?{\\|()\\\\\\?{\\)"
  4076. "\\((\\?\\??{\\)")) ; 5= (??{ (?{
  4077. "\\|" ; 6= 0-length, 7: name, 8,9:code, 10:group
  4078. "\\(" ;; XXXX 1-char variables, exc. |()\s
  4079. "[$@]"
  4080. "\\("
  4081. "[_a-zA-Z:][_a-zA-Z0-9:]*"
  4082. "\\|"
  4083. "{[^{}]*}" ; only one-level allowed
  4084. "\\|"
  4085. "[^{(|) \t\r\n\f]"
  4086. "\\)"
  4087. "\\(" ;;8,9:code part of array/hash elt
  4088. "\\(" "->" "\\)?"
  4089. "\\[[^][]*\\]"
  4090. "\\|"
  4091. "{[^{}]*}"
  4092. "\\)*"
  4093. ;; XXXX: what if u is delim?
  4094. "\\|"
  4095. "[)^|$.*?+]"
  4096. "\\|"
  4097. "{[0-9]+}"
  4098. "\\|"
  4099. "{[0-9]+,[0-9]*}"
  4100. "\\|"
  4101. "\\\\[luLUEQbBAzZG]"
  4102. "\\|"
  4103. "(" ; Group opener
  4104. "\\(" ; 10 group opener follower
  4105. "\\?\\((\\?\\)" ; 11: in (?(?=C)A|B)
  4106. "\\|"
  4107. "\\?[:=!>?{]" ; "?" something
  4108. "\\|"
  4109. "\\?[-imsx]+[:)]" ; (?i) (?-s:.)
  4110. "\\|"
  4111. "\\?([0-9]+)" ; (?(1)foo|bar)
  4112. "\\|"
  4113. "\\?<[=!]"
  4114. ;;;"\\|"
  4115. ;;; "\\?"
  4116. "\\)?"
  4117. "\\)"
  4118. "\\|"
  4119. "\\\\\\(.\\)" ; 12=\SYMBOL
  4120. ))
  4121. (while
  4122. (and (< (point) (1- e))
  4123. (re-search-forward hairy-RE (1- e) 'to-end))
  4124. (goto-char (match-beginning 0))
  4125. (setq REx-subgr-start (point)
  4126. was-subgr (following-char))
  4127. (cond
  4128. ((match-beginning 6) ; 0-length builtins, groups
  4129. (goto-char (match-end 0))
  4130. (if (match-beginning 11)
  4131. (goto-char (match-beginning 11)))
  4132. (if (>= (point) e)
  4133. (goto-char (1- e)))
  4134. (cperl-postpone-fontification
  4135. (match-beginning 0) (point)
  4136. 'face
  4137. (cond
  4138. ((eq was-subgr ?\) )
  4139. (condition-case nil
  4140. (save-excursion
  4141. (forward-sexp -1)
  4142. (if (> (point) b)
  4143. (if (if (eq (char-after b) ?? )
  4144. (looking-at "(\\\\\\?")
  4145. (eq (char-after (1+ (point))) ?\?))
  4146. my-cperl-REx-0length-face
  4147. my-cperl-REx-ctl-face)
  4148. font-lock-warning-face))
  4149. (error font-lock-warning-face)))
  4150. ((eq was-subgr ?\| )
  4151. my-cperl-REx-ctl-face)
  4152. ((eq was-subgr ?\$ )
  4153. (if (> (point) (1+ REx-subgr-start))
  4154. (progn
  4155. (put-text-property
  4156. (match-beginning 0) (point)
  4157. 'REx-interpolated
  4158. (if is-o-REx 0
  4159. (if (and (eq (match-beginning 0)
  4160. (1+ b))
  4161. (eq (point)
  4162. (1- e))) 1 t)))
  4163. font-lock-variable-name-face)
  4164. my-cperl-REx-spec-char-face))
  4165. ((memq was-subgr (append "^." nil) )
  4166. my-cperl-REx-spec-char-face)
  4167. ((eq was-subgr ?\( )
  4168. (if (not (match-beginning 10))
  4169. my-cperl-REx-ctl-face
  4170. my-cperl-REx-0length-face))
  4171. (t my-cperl-REx-0length-face)))
  4172. (if (and (memq was-subgr (append "(|" nil))
  4173. (not (string-match "(\\?[-imsx]+)"
  4174. (match-string 0))))
  4175. (cperl-look-at-leading-count is-x-REx e))
  4176. (setq was-subgr nil)) ; We do stuff here
  4177. ((match-beginning 12) ; \SYMBOL
  4178. (forward-char 2)
  4179. (if (>= (point) e)
  4180. (goto-char (1- e))
  4181. ;; How many chars to not highlight:
  4182. ;; 0-len special-alnums in other branch =>
  4183. ;; Generic: \non-alnum (1), \alnum (1+face)
  4184. ;; Is-delim: \non-alnum (1/spec-2) alnum-1 (=what hai)
  4185. (setq REx-subgr-start (point)
  4186. qtag (preceding-char))
  4187. (cperl-postpone-fontification
  4188. (- (point) 2) (- (point) 1) 'face
  4189. (if (memq qtag
  4190. (append "ghijkmoqvFHIJKMORTVY" nil))
  4191. font-lock-warning-face
  4192. my-cperl-REx-0length-face))
  4193. (if (and (eq (char-after b) qtag)
  4194. (memq qtag (append ".])^$|*?+" nil)))
  4195. (progn
  4196. (if (and cperl-use-syntax-table-text-property
  4197. (eq qtag ?\) ))
  4198. (put-text-property
  4199. REx-subgr-start (1- (point))
  4200. 'syntax-table cperl-st-punct))
  4201. (cperl-postpone-fontification
  4202. (1- (point)) (point) 'face
  4203. ; \] can't appear below
  4204. (if (memq qtag (append ".]^$" nil))
  4205. 'my-cperl-REx-spec-char-face
  4206. (if (memq qtag (append "*?+" nil))
  4207. 'my-cperl-REx-0length-face
  4208. 'my-cperl-REx-ctl-face))))) ; )|
  4209. ;; Test for arguments:
  4210. (cond
  4211. ;; This is not pretty: the 5.8.7 logic:
  4212. ;; \0numx -> octal (up to total 3 dig)
  4213. ;; \DIGIT -> backref unless \0
  4214. ;; \DIGITs -> backref if valid
  4215. ;; otherwise up to 3 -> octal
  4216. ;; Do not try to distinguish, we guess
  4217. ((or (and (memq qtag (append "01234567" nil))
  4218. (re-search-forward
  4219. "\\=[01234567]?[01234567]?"
  4220. (1- e) 'to-end))
  4221. (and (memq qtag (append "89" nil))
  4222. (re-search-forward
  4223. "\\=[0123456789]*" (1- e) 'to-end))
  4224. (and (eq qtag ?x)
  4225. (re-search-forward
  4226. "\\=[0-9a-fA-F][0-9a-fA-F]?\\|\\={[0-9a-fA-F]+}"
  4227. (1- e) 'to-end))
  4228. (and (memq qtag (append "pPN" nil))
  4229. (re-search-forward "\\={[^{}]+}\\|."
  4230. (1- e) 'to-end))
  4231. (eq (char-syntax qtag) ?w))
  4232. (cperl-postpone-fontification
  4233. (1- REx-subgr-start) (point)
  4234. 'face my-cperl-REx-length1-face))))
  4235. (setq was-subgr nil)) ; We do stuff here
  4236. ((match-beginning 3) ; [charclass]
  4237. ;; Highlight leader, trailer, POSIX classes
  4238. (forward-char 1)
  4239. (if (eq (char-after b) ?^ )
  4240. (and (eq (following-char) ?\\ )
  4241. (eq (char-after (cperl-1+ (point)))
  4242. ?^ )
  4243. (forward-char 2))
  4244. (and (eq (following-char) ?^ )
  4245. (forward-char 1)))
  4246. (setq argument b ; continue? & end of last POSIX
  4247. tag nil ; list of POSIX classes
  4248. qtag (point)) ; after leading ^ if present
  4249. (if (eq (char-after b) ?\] )
  4250. (and (eq (following-char) ?\\ )
  4251. (eq (char-after (cperl-1+ (point)))
  4252. ?\] )
  4253. (setq qtag (1+ qtag))
  4254. (forward-char 2))
  4255. (and (eq (following-char) ?\] )
  4256. (forward-char 1)))
  4257. (setq REx-subgr-end qtag) ;End smart-highlighted
  4258. ;; Apparently, I can't put \] into a charclass
  4259. ;; in m]]: m][\\\]\]] produces [\\]]
  4260. ;;; POSIX? [:word:] [:^word:] only inside []
  4261. ;;; "\\=\\(\\\\.\\|[^][\\\\]\\|\\[:\\^?\sw+:]\\|\\[[^:]\\)*]")
  4262. (while ; look for unescaped ]
  4263. (and argument
  4264. (re-search-forward
  4265. (if (eq (char-after b) ?\] )
  4266. "\\=\\(\\\\[^]]\\|[^]\\\\]\\)*\\\\]"
  4267. "\\=\\(\\\\.\\|[^]\\\\]\\)*]")
  4268. (1- e) 'toend))
  4269. ;; Is this ] an end of POSIX class?
  4270. (if (save-excursion
  4271. (and
  4272. (search-backward "[" argument t)
  4273. (< REx-subgr-start (point))
  4274. (setq argument (point)) ; POSIX-start
  4275. (or ; Should work with delim = \
  4276. (not (eq (preceding-char) ?\\ ))
  4277. ;; XXXX Double \\ is needed with 19.33
  4278. (= (% (skip-chars-backward "\\\\") 2) 0))
  4279. (looking-at
  4280. (cond
  4281. ((eq (char-after b) ?\] )
  4282. "\\\\*\\[:\\^?\\sw+:\\\\\\]")
  4283. ((eq (char-after b) ?\: )
  4284. "\\\\*\\[\\\\:\\^?\\sw+\\\\:]")
  4285. ((eq (char-after b) ?^ )
  4286. "\\\\*\\[:\\(\\\\\\^\\)?\\sw+:]")
  4287. ((eq (char-syntax (char-after b))
  4288. ?w)
  4289. (concat
  4290. "\\\\*\\[:\\(\\\\\\^\\)?\\(\\\\"
  4291. (char-to-string (char-after b))
  4292. "\\|\\sw\\)+:]"))
  4293. (t "\\\\*\\[:\\^?\\sw*:]")))
  4294. (goto-char REx-subgr-end)
  4295. (cperl-highlight-charclass
  4296. argument my-cperl-REx-spec-char-face
  4297. my-cperl-REx-0length-face my-cperl-REx-length1-face)))
  4298. (setq tag (cons (cons argument (point))
  4299. tag)
  4300. argument (point)
  4301. REx-subgr-end argument) ; continue
  4302. (setq argument nil)))
  4303. (and argument
  4304. (message "Couldn't find end of charclass in a REx, pos=%s"
  4305. REx-subgr-start))
  4306. (setq argument (1- (point)))
  4307. (goto-char REx-subgr-end)
  4308. (cperl-highlight-charclass
  4309. argument my-cperl-REx-spec-char-face
  4310. my-cperl-REx-0length-face my-cperl-REx-length1-face)
  4311. (forward-char 1)
  4312. ;; Highlight starter, trailer, POSIX
  4313. (if (and cperl-use-syntax-table-text-property
  4314. (> (- (point) 2) REx-subgr-start))
  4315. (put-text-property
  4316. (1+ REx-subgr-start) (1- (point))
  4317. 'syntax-table cperl-st-punct))
  4318. (cperl-postpone-fontification
  4319. REx-subgr-start qtag
  4320. 'face my-cperl-REx-spec-char-face)
  4321. (cperl-postpone-fontification
  4322. (1- (point)) (point) 'face
  4323. my-cperl-REx-spec-char-face)
  4324. (if (eq (char-after b) ?\] )
  4325. (cperl-postpone-fontification
  4326. (- (point) 2) (1- (point))
  4327. 'face my-cperl-REx-0length-face))
  4328. (while tag
  4329. (cperl-postpone-fontification
  4330. (car (car tag)) (cdr (car tag))
  4331. 'face font-lock-variable-name-face) ;my-cperl-REx-length1-face
  4332. (setq tag (cdr tag)))
  4333. (setq was-subgr nil)) ; did facing already
  4334. ;; Now rare stuff:
  4335. ((and (match-beginning 2) ; #-comment
  4336. (/= (match-beginning 2) (match-end 2)))
  4337. (beginning-of-line 2)
  4338. (if (> (point) e)
  4339. (goto-char (1- e))))
  4340. ((match-beginning 4) ; character "]"
  4341. (setq was-subgr nil) ; We do stuff here
  4342. (goto-char (match-end 0))
  4343. (if cperl-use-syntax-table-text-property
  4344. (put-text-property
  4345. (1- (point)) (point)
  4346. 'syntax-table cperl-st-punct))
  4347. (cperl-postpone-fontification
  4348. (1- (point)) (point)
  4349. 'face font-lock-warning-face))
  4350. ((match-beginning 5) ; before (?{}) (??{})
  4351. (setq tag (match-end 0))
  4352. (if (or (setq qtag
  4353. (cperl-forward-group-in-re st-l))
  4354. (and (>= (point) e)
  4355. (setq qtag "no matching `)' found"))
  4356. (and (not (eq (char-after (- (point) 2))
  4357. ?\} ))
  4358. (setq qtag "Can't find })")))
  4359. (progn
  4360. (goto-char (1- e))
  4361. (message "%s" qtag))
  4362. (cperl-postpone-fontification
  4363. (1- tag) (1- (point))
  4364. 'face font-lock-variable-name-face)
  4365. (cperl-postpone-fontification
  4366. REx-subgr-start (1- tag)
  4367. 'face my-cperl-REx-spec-char-face)
  4368. (cperl-postpone-fontification
  4369. (1- (point)) (point)
  4370. 'face my-cperl-REx-spec-char-face)
  4371. (if cperl-use-syntax-table-text-property
  4372. (progn
  4373. (put-text-property
  4374. (- (point) 2) (1- (point))
  4375. 'syntax-table cperl-st-cfence)
  4376. (put-text-property
  4377. (+ REx-subgr-start 2)
  4378. (+ REx-subgr-start 3)
  4379. 'syntax-table cperl-st-cfence))))
  4380. (setq was-subgr nil))
  4381. (t ; (?#)-comment
  4382. ;; Inside "(" and "\" arn't special in any way
  4383. ;; Works also if the outside delimiters are ().
  4384. (or;;(if (eq (char-after b) ?\) )
  4385. ;;(re-search-forward
  4386. ;; "[^\\\\]\\(\\\\\\\\\\)*\\\\)"
  4387. ;; (1- e) 'toend)
  4388. (search-forward ")" (1- e) 'toend)
  4389. ;;)
  4390. (message
  4391. "Couldn't find end of (?#...)-comment in a REx, pos=%s"
  4392. REx-subgr-start))))
  4393. (if (>= (point) e)
  4394. (goto-char (1- e)))
  4395. (cond
  4396. (was-subgr
  4397. (setq REx-subgr-end (point))
  4398. (cperl-commentify
  4399. REx-subgr-start REx-subgr-end nil)
  4400. (cperl-postpone-fontification
  4401. REx-subgr-start REx-subgr-end
  4402. 'face font-lock-comment-face))))))
  4403. (if (and is-REx is-x-REx)
  4404. (put-text-property (1+ b) (1- e)
  4405. 'syntax-subtype 'x-REx)))
  4406. (if (and i2 e1 (or (not b1) (> e1 b1)))
  4407. (progn ; No errors finding the second part...
  4408. (cperl-postpone-fontification
  4409. (1- e1) e1 'face my-cperl-delimiters-face)
  4410. (if (and (not (eobp))
  4411. (assoc (char-after b) cperl-starters))
  4412. (progn
  4413. (cperl-postpone-fontification
  4414. b1 (1+ b1) 'face my-cperl-delimiters-face)
  4415. (put-text-property b1 (1+ b1)
  4416. 'REx-part2 t)))))
  4417. (if (> (point) max)
  4418. (setq tmpend tb))))
  4419. ((match-beginning 17) ; sub with prototype or attribute
  4420. ;; 1+6+2+1+1=11 extra () before this (sub with proto/attr):
  4421. ;;"\\<sub\\>\\(" ;12
  4422. ;; cperl-white-and-comment-rex ;13
  4423. ;; "\\([a-zA-Z_:'0-9]+\\)\\)?" ; name ;14
  4424. ;;"\\(" cperl-maybe-white-and-comment-rex ;15,16
  4425. ;; "\\(([^()]*)\\|:[^:]\\)\\)" ; 17:proto or attribute start
  4426. (setq b1 (match-beginning 14) e1 (match-end 14))
  4427. (if (memq (char-after (1- b))
  4428. '(?\$ ?\@ ?\% ?\& ?\*))
  4429. nil
  4430. (goto-char b)
  4431. (if (eq (char-after (match-beginning 17)) ?\( )
  4432. (progn
  4433. (cperl-commentify ; Prototypes; mark as string
  4434. (match-beginning 17) (match-end 17) t)
  4435. (goto-char (match-end 0))
  4436. ;; Now look for attributes after prototype:
  4437. (forward-comment (buffer-size))
  4438. (and (looking-at ":[^:]")
  4439. (cperl-find-sub-attrs st-l b1 e1 b)))
  4440. ;; treat attributes without prototype
  4441. (goto-char (match-beginning 17))
  4442. (cperl-find-sub-attrs st-l b1 e1 b))))
  4443. ;; 1+6+2+1+1+6+1=18 extra () before this:
  4444. ;; "\\(\\<sub[ \t\n\f]+\\|[&*$@%]\\)[a-zA-Z0-9_]*'")
  4445. ((match-beginning 19) ; old $abc'efg syntax
  4446. (setq bb (match-end 0))
  4447. ;;;(if (nth 3 state) nil ; in string
  4448. (put-text-property (1- bb) bb 'syntax-table cperl-st-word)
  4449. (goto-char bb))
  4450. ;; 1+6+2+1+1+6+1+1=19 extra () before this:
  4451. ;; "__\\(END\\|DATA\\)__"
  4452. ((match-beginning 20) ; __END__, __DATA__
  4453. (setq bb (match-end 0))
  4454. ;; (put-text-property b (1+ bb) 'syntax-type 'pod) ; Cheat
  4455. (cperl-commentify b bb nil)
  4456. (setq end t))
  4457. ;; "\\\\\\(['`\"($]\\)"
  4458. ((match-beginning 21)
  4459. ;; Trailing backslash; make non-quoting outside string/comment
  4460. (setq bb (match-end 0))
  4461. (goto-char b)
  4462. (skip-chars-backward "\\\\")
  4463. ;;;(setq i2 (= (% (skip-chars-backward "\\\\") 2) -1))
  4464. (cperl-modify-syntax-type b cperl-st-punct)
  4465. (goto-char bb))
  4466. (t (error "Error in regexp of the sniffer")))
  4467. (if (> (point) stop-point)
  4468. (progn
  4469. (if end
  4470. (message "Garbage after __END__/__DATA__ ignored")
  4471. (message "Unbalanced syntax found while scanning")
  4472. (or (car err-l) (setcar err-l b)))
  4473. (goto-char stop-point))))
  4474. (setq cperl-syntax-state (cons state-point state)
  4475. ;; Do not mark syntax as done past tmpend???
  4476. cperl-syntax-done-to (or tmpend (max (point) max)))
  4477. ;;(message "state-at=%s, done-to=%s" state-point cperl-syntax-done-to)
  4478. )
  4479. (if (car err-l) (goto-char (car err-l))
  4480. (or non-inter
  4481. (message "Scanning for \"hard\" Perl constructions... done"))))
  4482. (and (buffer-modified-p)
  4483. (not modified)
  4484. (set-buffer-modified-p nil))
  4485. ;; I do not understand what this is doing here. It breaks font-locking
  4486. ;; because it resets the syntax-table from font-lock-syntax-table to
  4487. ;; cperl-mode-syntax-table.
  4488. ;; (set-syntax-table cperl-mode-syntax-table)
  4489. )
  4490. (list (car err-l) overshoot)))
  4491. (defun cperl-find-pods-heres-region (min max)
  4492. (interactive "r")
  4493. (cperl-find-pods-heres min max))
  4494. (defun cperl-backward-to-noncomment (lim)
  4495. ;; Stops at lim or after non-whitespace that is not in comment
  4496. ;; XXXX Wrongly understands end-of-multiline strings with # as comment
  4497. (let (stop p pr)
  4498. (while (and (not stop) (> (point) (or lim (point-min))))
  4499. (skip-chars-backward " \t\n\f" lim)
  4500. (setq p (point))
  4501. (beginning-of-line)
  4502. (if (memq (setq pr (get-text-property (point) 'syntax-type))
  4503. '(pod here-doc here-doc-delim))
  4504. (progn
  4505. (cperl-unwind-to-safe nil)
  4506. (setq pr (get-text-property (point) 'syntax-type))))
  4507. (or (and (looking-at "^[ \t]*\\(#\\|$\\)")
  4508. (not (memq pr '(string prestring))))
  4509. (progn (cperl-to-comment-or-eol) (bolp))
  4510. (progn
  4511. (skip-chars-backward " \t")
  4512. (if (< p (point)) (goto-char p))
  4513. (setq stop t))))))
  4514. ;; Used only in `cperl-calculate-indent'...
  4515. (defun cperl-block-p () ; Do not C-M-q ! One string contains ";" !
  4516. ;; Positions is before ?\{. Checks whether it starts a block.
  4517. ;; No save-excursion! This is more a distinguisher of a block/hash ref...
  4518. (cperl-backward-to-noncomment (point-min))
  4519. (or (memq (preceding-char) (append ";){}$@&%\C-@" nil)) ; Or label! \C-@ at bobp
  4520. ; Label may be mixed up with `$blah :'
  4521. (save-excursion (cperl-after-label))
  4522. (get-text-property (cperl-1- (point)) 'attrib-group)
  4523. (and (memq (char-syntax (preceding-char)) '(?w ?_))
  4524. (progn
  4525. (backward-sexp)
  4526. ;; sub {BLK}, print {BLK} $data, but NOT `bless', `return', `tr', `constant'
  4527. (or (and (looking-at "[a-zA-Z0-9_:]+[ \t\n\f]*[{#]") ; Method call syntax
  4528. (not (looking-at "\\(bless\\|return\\|q[wqrx]?\\|tr\\|[smy]\\|constant\\)\\>")))
  4529. ;; sub bless::foo {}
  4530. (progn
  4531. (cperl-backward-to-noncomment (point-min))
  4532. (and (eq (preceding-char) ?b)
  4533. (progn
  4534. (forward-sexp -1)
  4535. (looking-at "sub[ \t\n\f#]")))))))))
  4536. ;;; What is the difference of (cperl-after-block-p lim t) and (cperl-block-p)?
  4537. ;;; No save-excursion; condition-case ... In (cperl-block-p) the block
  4538. ;;; may be a part of an in-statement construct, such as
  4539. ;;; ${something()}, print {FH} $data.
  4540. ;;; Moreover, one takes positive approach (looks for else,grep etc)
  4541. ;;; another negative (looks for bless,tr etc)
  4542. (defun cperl-after-block-p (lim &optional pre-block)
  4543. "Return true if the preceding } (if PRE-BLOCK, following {) delimits a block.
  4544. Would not look before LIM. Assumes that LIM is a good place to begin a
  4545. statement. The kind of block we treat here is one after which a new
  4546. statement would start; thus the block in ${func()} does not count."
  4547. (save-excursion
  4548. (condition-case nil
  4549. (progn
  4550. (or pre-block (forward-sexp -1))
  4551. (cperl-backward-to-noncomment lim)
  4552. (or (eq (point) lim)
  4553. ;; if () {} // sub f () {} // sub f :a(') {}
  4554. (eq (preceding-char) ?\) )
  4555. ;; label: {}
  4556. (save-excursion (cperl-after-label))
  4557. ;; sub :attr {}
  4558. (get-text-property (cperl-1- (point)) 'attrib-group)
  4559. (if (memq (char-syntax (preceding-char)) '(?w ?_)) ; else {}
  4560. (save-excursion
  4561. (forward-sexp -1)
  4562. ;; else {} but not else::func {}
  4563. (or (and (looking-at "\\(else\\|continue\\|grep\\|map\\|BEGIN\\|END\\|CHECK\\|INIT\\)\\>")
  4564. (not (looking-at "\\(\\sw\\|_\\)+::")))
  4565. ;; sub f {}
  4566. (progn
  4567. (cperl-backward-to-noncomment lim)
  4568. (and (eq (preceding-char) ?b)
  4569. (progn
  4570. (forward-sexp -1)
  4571. (looking-at "sub[ \t\n\f#]"))))))
  4572. ;; What precedes is not word... XXXX Last statement in sub???
  4573. (cperl-after-expr-p lim))))
  4574. (error nil))))
  4575. (defun cperl-after-expr-p (&optional lim chars test)
  4576. "Return true if the position is good for start of expression.
  4577. TEST is the expression to evaluate at the found position. If absent,
  4578. CHARS is a string that contains good characters to have before us (however,
  4579. `}' is treated \"smartly\" if it is not in the list)."
  4580. (let ((lim (or lim (point-min)))
  4581. stop p pr)
  4582. (cperl-update-syntaxification (point) (point))
  4583. (save-excursion
  4584. (while (and (not stop) (> (point) lim))
  4585. (skip-chars-backward " \t\n\f" lim)
  4586. (setq p (point))
  4587. (beginning-of-line)
  4588. ;;(memq (setq pr (get-text-property (point) 'syntax-type))
  4589. ;; '(pod here-doc here-doc-delim))
  4590. (if (get-text-property (point) 'here-doc-group)
  4591. (progn
  4592. (goto-char
  4593. (cperl-beginning-of-property (point) 'here-doc-group))
  4594. (beginning-of-line 0)))
  4595. (if (get-text-property (point) 'in-pod)
  4596. (progn
  4597. (goto-char
  4598. (cperl-beginning-of-property (point) 'in-pod))
  4599. (beginning-of-line 0)))
  4600. (if (looking-at "^[ \t]*\\(#\\|$\\)") nil ; Only comment, skip
  4601. ;; Else: last iteration, or a label
  4602. (cperl-to-comment-or-eol) ; Will not move past "." after a format
  4603. (skip-chars-backward " \t")
  4604. (if (< p (point)) (goto-char p))
  4605. (setq p (point))
  4606. (if (and (eq (preceding-char) ?:)
  4607. (progn
  4608. (forward-char -1)
  4609. (skip-chars-backward " \t\n\f" lim)
  4610. (memq (char-syntax (preceding-char)) '(?w ?_))))
  4611. (forward-sexp -1) ; Possibly label. Skip it
  4612. (goto-char p)
  4613. (setq stop t))))
  4614. (or (bobp) ; ???? Needed
  4615. (eq (point) lim)
  4616. (looking-at "[ \t]*__\\(END\\|DATA\\)__") ; After this anything goes
  4617. (progn
  4618. (if test (eval test)
  4619. (or (memq (preceding-char) (append (or chars "{;") nil))
  4620. (and (eq (preceding-char) ?\})
  4621. (cperl-after-block-p lim))
  4622. (and (eq (following-char) ?.) ; in format: see comment above
  4623. (eq (get-text-property (point) 'syntax-type)
  4624. 'format)))))))))
  4625. (defun cperl-backward-to-start-of-expr (&optional lim)
  4626. (condition-case nil
  4627. (progn
  4628. (while (and (or (not lim)
  4629. (> (point) lim))
  4630. (not (cperl-after-expr-p lim)))
  4631. (forward-sexp -1)
  4632. ;; May be after $, @, $# etc of a variable
  4633. (skip-chars-backward "$@%#")))
  4634. (error nil)))
  4635. (defun cperl-at-end-of-expr (&optional lim)
  4636. ;; Since the SEXP approach below is very fragile, do some overengineering
  4637. (or (looking-at (concat cperl-maybe-white-and-comment-rex "[;}]"))
  4638. (condition-case nil
  4639. (save-excursion
  4640. ;; If nothing interesting after, does as (forward-sexp -1);
  4641. ;; otherwise fails, or ends at a start of following sexp.
  4642. ;; XXXX PROBLEMS: if what follows (after ";") @FOO, or ${bar}
  4643. ;; may be stuck after @ or $; just put some stupid workaround now:
  4644. (let ((p (point)))
  4645. (forward-sexp 1)
  4646. (forward-sexp -1)
  4647. (while (memq (preceding-char) (append "%&@$*" nil))
  4648. (forward-char -1))
  4649. (or (< (point) p)
  4650. (cperl-after-expr-p lim))))
  4651. (error t))))
  4652. (defun cperl-forward-to-end-of-expr (&optional lim)
  4653. (let ((p (point))))
  4654. (condition-case nil
  4655. (progn
  4656. (while (and (< (point) (or lim (point-max)))
  4657. (not (cperl-at-end-of-expr)))
  4658. (forward-sexp 1)))
  4659. (error nil)))
  4660. (defun cperl-backward-to-start-of-continued-exp (lim)
  4661. (if (memq (preceding-char) (append ")]}\"'`" nil))
  4662. (forward-sexp -1))
  4663. (beginning-of-line)
  4664. (if (<= (point) lim)
  4665. (goto-char (1+ lim)))
  4666. (skip-chars-forward " \t"))
  4667. (defun cperl-after-block-and-statement-beg (lim)
  4668. ;; We assume that we are after ?\}
  4669. (and
  4670. (cperl-after-block-p lim)
  4671. (save-excursion
  4672. (forward-sexp -1)
  4673. (cperl-backward-to-noncomment (point-min))
  4674. (or (bobp)
  4675. (eq (point) lim)
  4676. (not (= (char-syntax (preceding-char)) ?w))
  4677. (progn
  4678. (forward-sexp -1)
  4679. (not
  4680. (looking-at
  4681. "\\(map\\|grep\\|printf?\\|system\\|exec\\|tr\\|s\\)\\>")))))))
  4682. (defun cperl-indent-exp ()
  4683. "Simple variant of indentation of continued-sexp.
  4684. Will not indent comment if it starts at `comment-indent' or looks like
  4685. continuation of the comment on the previous line.
  4686. If `cperl-indent-region-fix-constructs', will improve spacing on
  4687. conditional/loop constructs."
  4688. (interactive)
  4689. (save-excursion
  4690. (let ((tmp-end (point-at-eol)) top done)
  4691. (save-excursion
  4692. (beginning-of-line)
  4693. (while (null done)
  4694. (setq top (point))
  4695. ;; Plan A: if line has an unfinished paren-group, go to end-of-group
  4696. (while (= -1 (nth 0 (parse-partial-sexp (point) tmp-end -1)))
  4697. (setq top (point))) ; Get the outermost parens in line
  4698. (goto-char top)
  4699. (while (< (point) tmp-end)
  4700. (parse-partial-sexp (point) tmp-end nil t) ; To start-sexp or eol
  4701. (or (eolp) (forward-sexp 1)))
  4702. (if (> (point) tmp-end) ; Yes, there an unfinished block
  4703. nil
  4704. (if (eq ?\) (preceding-char))
  4705. (progn ;; Plan B: find by REGEXP block followup this line
  4706. (setq top (point))
  4707. (condition-case nil
  4708. (progn
  4709. (forward-sexp -2)
  4710. (if (eq (following-char) ?$ ) ; for my $var (list)
  4711. (progn
  4712. (forward-sexp -1)
  4713. (if (looking-at "\\(my\\|local\\|our\\)\\>")
  4714. (forward-sexp -1))))
  4715. (if (looking-at
  4716. (concat "\\(\\elsif\\|if\\|unless\\|while\\|until"
  4717. "\\|for\\(each\\)?\\>\\(\\("
  4718. cperl-maybe-white-and-comment-rex
  4719. "\\(my\\|local\\|our\\)\\)?"
  4720. cperl-maybe-white-and-comment-rex
  4721. "\\$[_a-zA-Z0-9]+\\)?\\)\\>"))
  4722. (progn
  4723. (goto-char top)
  4724. (forward-sexp 1)
  4725. (setq top (point)))))
  4726. (error (setq done t)))
  4727. (goto-char top))
  4728. (if (looking-at ; Try Plan C: continuation block
  4729. (concat cperl-maybe-white-and-comment-rex
  4730. "\\<\\(else\\|elsif\\|continue\\)\\>"))
  4731. (progn
  4732. (goto-char (match-end 0))
  4733. (setq tmp-end (point-at-eol)))
  4734. (setq done t))))
  4735. (setq tmp-end (point-at-eol)))
  4736. (goto-char tmp-end)
  4737. (setq tmp-end (point-marker)))
  4738. (if cperl-indent-region-fix-constructs
  4739. (cperl-fix-line-spacing tmp-end))
  4740. (cperl-indent-region (point) tmp-end))))
  4741. (defun cperl-fix-line-spacing (&optional end parse-data)
  4742. "Improve whitespace in a conditional/loop construct.
  4743. Returns some position at the last line."
  4744. (interactive)
  4745. (or end
  4746. (setq end (point-max)))
  4747. (let ((ee (point-at-eol))
  4748. (cperl-indent-region-fix-constructs
  4749. (or cperl-indent-region-fix-constructs 1))
  4750. p pp ml have-brace ret)
  4751. (save-excursion
  4752. (beginning-of-line)
  4753. (setq ret (point))
  4754. ;; }? continue
  4755. ;; blah; }
  4756. (if (not
  4757. (or (looking-at "[ \t]*\\(els\\(e\\|if\\)\\|continue\\|if\\|while\\|for\\(each\\)?\\|until\\)")
  4758. (setq have-brace (save-excursion (search-forward "}" ee t)))))
  4759. nil ; Do not need to do anything
  4760. ;; Looking at:
  4761. ;; }
  4762. ;; else
  4763. (if cperl-merge-trailing-else
  4764. (if (looking-at
  4765. "[ \t]*}[ \t]*\n[ \t\n]*\\(els\\(e\\|if\\)\\|continue\\)\\>")
  4766. (progn
  4767. (search-forward "}")
  4768. (setq p (point))
  4769. (skip-chars-forward " \t\n")
  4770. (delete-region p (point))
  4771. (insert (make-string cperl-indent-region-fix-constructs ?\s))
  4772. (beginning-of-line)))
  4773. (if (looking-at "[ \t]*}[ \t]*\\(els\\(e\\|if\\)\\|continue\\)\\>")
  4774. (save-excursion
  4775. (search-forward "}")
  4776. (delete-horizontal-space)
  4777. (insert "\n")
  4778. (setq ret (point))
  4779. (if (cperl-indent-line parse-data)
  4780. (progn
  4781. (cperl-fix-line-spacing end parse-data)
  4782. (setq ret (point)))))))
  4783. ;; Looking at:
  4784. ;; } else
  4785. (if (looking-at "[ \t]*}\\(\t*\\|[ \t][ \t]+\\)\\<\\(els\\(e\\|if\\)\\|continue\\)\\>")
  4786. (progn
  4787. (search-forward "}")
  4788. (delete-horizontal-space)
  4789. (insert (make-string cperl-indent-region-fix-constructs ?\s))
  4790. (beginning-of-line)))
  4791. ;; Looking at:
  4792. ;; else {
  4793. (if (looking-at
  4794. "[ \t]*}?[ \t]*\\<\\(\\els\\(e\\|if\\)\\|continue\\|unless\\|if\\|while\\|for\\(each\\)?\\|until\\)\\>\\(\t*\\|[ \t][ \t]+\\)[^ \t\n#]")
  4795. (progn
  4796. (forward-word 1)
  4797. (delete-horizontal-space)
  4798. (insert (make-string cperl-indent-region-fix-constructs ?\s))
  4799. (beginning-of-line)))
  4800. ;; Looking at:
  4801. ;; foreach my $var
  4802. (if (looking-at
  4803. "[ \t]*\\<for\\(each\\)?[ \t]+\\(my\\|local\\|our\\)\\(\t*\\|[ \t][ \t]+\\)[^ \t\n]")
  4804. (progn
  4805. (forward-word 2)
  4806. (delete-horizontal-space)
  4807. (insert (make-string cperl-indent-region-fix-constructs ?\s))
  4808. (beginning-of-line)))
  4809. ;; Looking at:
  4810. ;; foreach my $var (
  4811. (if (looking-at
  4812. "[ \t]*\\<for\\(each\\)?[ \t]+\\(my\\|local\\|our\\)[ \t]*\\$[_a-zA-Z0-9]+\\(\t*\\|[ \t][ \t]+\\)[^ \t\n#]")
  4813. (progn
  4814. (forward-sexp 3)
  4815. (delete-horizontal-space)
  4816. (insert
  4817. (make-string cperl-indent-region-fix-constructs ?\s))
  4818. (beginning-of-line)))
  4819. ;; Looking at (with or without "}" at start, ending after "({"):
  4820. ;; } foreach my $var () OR {
  4821. (if (looking-at
  4822. "[ \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]*{")
  4823. (progn
  4824. (setq ml (match-beginning 8)) ; "(" or "{" after control word
  4825. (re-search-forward "[({]")
  4826. (forward-char -1)
  4827. (setq p (point))
  4828. (if (eq (following-char) ?\( )
  4829. (progn
  4830. (forward-sexp 1)
  4831. (setq pp (point))) ; past parenthesis-group
  4832. ;; after `else' or nothing
  4833. (if ml ; after `else'
  4834. (skip-chars-backward " \t\n")
  4835. (beginning-of-line))
  4836. (setq pp nil))
  4837. ;; Now after the sexp before the brace
  4838. ;; Multiline expr should be special
  4839. (setq ml (and pp (save-excursion (goto-char p)
  4840. (search-forward "\n" pp t))))
  4841. (if (and (or (not pp) (< pp end)) ; Do not go too far...
  4842. (looking-at "[ \t\n]*{"))
  4843. (progn
  4844. (cond
  4845. ((bolp) ; Were before `{', no if/else/etc
  4846. nil)
  4847. ((looking-at "\\(\t*\\| [ \t]+\\){") ; Not exactly 1 SPACE
  4848. (delete-horizontal-space)
  4849. (if (if ml
  4850. cperl-extra-newline-before-brace-multiline
  4851. cperl-extra-newline-before-brace)
  4852. (progn
  4853. (delete-horizontal-space)
  4854. (insert "\n")
  4855. (setq ret (point))
  4856. (if (cperl-indent-line parse-data)
  4857. (progn
  4858. (cperl-fix-line-spacing end parse-data)
  4859. (setq ret (point)))))
  4860. (insert
  4861. (make-string cperl-indent-region-fix-constructs ?\s))))
  4862. ((and (looking-at "[ \t]*\n")
  4863. (not (if ml
  4864. cperl-extra-newline-before-brace-multiline
  4865. cperl-extra-newline-before-brace)))
  4866. (setq pp (point))
  4867. (skip-chars-forward " \t\n")
  4868. (delete-region pp (point))
  4869. (insert
  4870. (make-string cperl-indent-region-fix-constructs ?\ )))
  4871. ((and (looking-at "[\t ]*{")
  4872. (if ml cperl-extra-newline-before-brace-multiline
  4873. cperl-extra-newline-before-brace))
  4874. (delete-horizontal-space)
  4875. (insert "\n")
  4876. (setq ret (point))
  4877. (if (cperl-indent-line parse-data)
  4878. (progn
  4879. (cperl-fix-line-spacing end parse-data)
  4880. (setq ret (point))))))
  4881. ;; Now we are before `{'
  4882. (if (looking-at "[ \t\n]*{[ \t]*[^ \t\n#]")
  4883. (progn
  4884. (skip-chars-forward " \t\n")
  4885. (setq pp (point))
  4886. (forward-sexp 1)
  4887. (setq p (point))
  4888. (goto-char pp)
  4889. (setq ml (search-forward "\n" p t))
  4890. (if (or cperl-break-one-line-blocks-when-indent ml)
  4891. ;; not good: multi-line BLOCK
  4892. (progn
  4893. (goto-char (1+ pp))
  4894. (delete-horizontal-space)
  4895. (insert "\n")
  4896. (setq ret (point))
  4897. (if (cperl-indent-line parse-data)
  4898. (setq ret (cperl-fix-line-spacing end parse-data)))))))))))
  4899. (beginning-of-line)
  4900. (setq p (point) pp (point-at-eol)) ; May be different from ee.
  4901. ;; Now check whether there is a hanging `}'
  4902. ;; Looking at:
  4903. ;; } blah
  4904. (if (and
  4905. cperl-fix-hanging-brace-when-indent
  4906. have-brace
  4907. (not (looking-at "[ \t]*}[ \t]*\\(\\<\\(els\\(if\\|e\\)\\|continue\\|while\\|until\\)\\>\\|$\\|#\\)"))
  4908. (condition-case nil
  4909. (progn
  4910. (up-list 1)
  4911. (if (and (<= (point) pp)
  4912. (eq (preceding-char) ?\} )
  4913. (cperl-after-block-and-statement-beg (point-min)))
  4914. t
  4915. (goto-char p)
  4916. nil))
  4917. (error nil)))
  4918. (progn
  4919. (forward-char -1)
  4920. (skip-chars-backward " \t")
  4921. (if (bolp)
  4922. ;; `}' was the first thing on the line, insert NL *after* it.
  4923. (progn
  4924. (cperl-indent-line parse-data)
  4925. (search-forward "}")
  4926. (delete-horizontal-space)
  4927. (insert "\n"))
  4928. (delete-horizontal-space)
  4929. (or (eq (preceding-char) ?\;)
  4930. (bolp)
  4931. (and (eq (preceding-char) ?\} )
  4932. (cperl-after-block-p (point-min)))
  4933. (insert ";"))
  4934. (insert "\n")
  4935. (setq ret (point)))
  4936. (if (cperl-indent-line parse-data)
  4937. (setq ret (cperl-fix-line-spacing end parse-data)))
  4938. (beginning-of-line)))))
  4939. ret))
  4940. (defvar cperl-update-start) ; Do not need to make them local
  4941. (defvar cperl-update-end)
  4942. (defun cperl-delay-update-hook (beg end old-len)
  4943. (setq cperl-update-start (min beg (or cperl-update-start (point-max))))
  4944. (setq cperl-update-end (max end (or cperl-update-end (point-min)))))
  4945. (defun cperl-indent-region (start end)
  4946. "Simple variant of indentation of region in CPerl mode.
  4947. Should be slow. Will not indent comment if it starts at `comment-indent'
  4948. or looks like continuation of the comment on the previous line.
  4949. Indents all the lines whose first character is between START and END
  4950. inclusive.
  4951. If `cperl-indent-region-fix-constructs', will improve spacing on
  4952. conditional/loop constructs."
  4953. (interactive "r")
  4954. (cperl-update-syntaxification end end)
  4955. (save-excursion
  4956. (let (cperl-update-start cperl-update-end (h-a-c after-change-functions))
  4957. (let ((indent-info (if cperl-emacs-can-parse
  4958. (list nil nil nil) ; Cannot use '(), since will modify
  4959. nil))
  4960. (pm 0)
  4961. after-change-functions ; Speed it up!
  4962. st comm old-comm-indent new-comm-indent p pp i empty)
  4963. (if h-a-c (add-hook 'after-change-functions 'cperl-delay-update-hook))
  4964. (goto-char start)
  4965. (setq old-comm-indent (and (cperl-to-comment-or-eol)
  4966. (current-column))
  4967. new-comm-indent old-comm-indent)
  4968. (goto-char start)
  4969. (setq end (set-marker (make-marker) end)) ; indentation changes pos
  4970. (or (bolp) (beginning-of-line 2))
  4971. (while (and (<= (point) end) (not (eobp))) ; bol to check start
  4972. (setq st (point))
  4973. (if (or
  4974. (setq empty (looking-at "[ \t]*\n"))
  4975. (and (setq comm (looking-at "[ \t]*#"))
  4976. (or (eq (current-indentation) (or old-comm-indent
  4977. comment-column))
  4978. (setq old-comm-indent nil))))
  4979. (if (and old-comm-indent
  4980. (not empty)
  4981. (= (current-indentation) old-comm-indent)
  4982. (not (eq (get-text-property (point) 'syntax-type) 'pod))
  4983. (not (eq (get-text-property (point) 'syntax-table)
  4984. cperl-st-cfence)))
  4985. (let ((comment-column new-comm-indent))
  4986. (indent-for-comment)))
  4987. (progn
  4988. (setq i (cperl-indent-line indent-info))
  4989. (or comm
  4990. (not i)
  4991. (progn
  4992. (if cperl-indent-region-fix-constructs
  4993. (goto-char (cperl-fix-line-spacing end indent-info)))
  4994. (if (setq old-comm-indent
  4995. (and (cperl-to-comment-or-eol)
  4996. (not (memq (get-text-property (point)
  4997. 'syntax-type)
  4998. '(pod here-doc)))
  4999. (not (eq (get-text-property (point)
  5000. 'syntax-table)
  5001. cperl-st-cfence))
  5002. (current-column)))
  5003. (progn (indent-for-comment)
  5004. (skip-chars-backward " \t")
  5005. (skip-chars-backward "#")
  5006. (setq new-comm-indent (current-column))))))))
  5007. (beginning-of-line 2)))
  5008. ;; Now run the update hooks
  5009. (and after-change-functions
  5010. cperl-update-end
  5011. (save-excursion
  5012. (goto-char cperl-update-end)
  5013. (insert " ")
  5014. (delete-char -1)
  5015. (goto-char cperl-update-start)
  5016. (insert " ")
  5017. (delete-char -1))))))
  5018. ;; Stolen from lisp-mode with a lot of improvements
  5019. (defun cperl-fill-paragraph (&optional justify iteration)
  5020. "Like `fill-paragraph', but handle CPerl comments.
  5021. If any of the current line is a comment, fill the comment or the
  5022. block of it that point is in, preserving the comment's initial
  5023. indentation and initial hashes. Behaves usually outside of comment."
  5024. ;; (interactive "P") ; Only works when called from fill-paragraph. -stef
  5025. (let (;; Non-nil if the current line contains a comment.
  5026. has-comment
  5027. fill-paragraph-function ; do not recurse
  5028. ;; If has-comment, the appropriate fill-prefix for the comment.
  5029. comment-fill-prefix
  5030. ;; Line that contains code and comment (or nil)
  5031. start
  5032. c spaces len dc (comment-column comment-column))
  5033. ;; Figure out what kind of comment we are looking at.
  5034. (save-excursion
  5035. (beginning-of-line)
  5036. (cond
  5037. ;; A line with nothing but a comment on it?
  5038. ((looking-at "[ \t]*#[# \t]*")
  5039. (setq has-comment t
  5040. comment-fill-prefix (buffer-substring (match-beginning 0)
  5041. (match-end 0))))
  5042. ;; A line with some code, followed by a comment? Remember that the
  5043. ;; semi which starts the comment shouldn't be part of a string or
  5044. ;; character.
  5045. ((cperl-to-comment-or-eol)
  5046. (setq has-comment t)
  5047. (looking-at "#+[ \t]*")
  5048. (setq start (point) c (current-column)
  5049. comment-fill-prefix
  5050. (concat (make-string (current-column) ?\s)
  5051. (buffer-substring (match-beginning 0) (match-end 0)))
  5052. spaces (progn (skip-chars-backward " \t")
  5053. (buffer-substring (point) start))
  5054. dc (- c (current-column)) len (- start (point))
  5055. start (point-marker))
  5056. (delete-char len)
  5057. (insert (make-string dc ?-))))) ; Placeholder (to avoid splitting???)
  5058. (if (not has-comment)
  5059. (fill-paragraph justify) ; Do the usual thing outside of comment
  5060. ;; Narrow to include only the comment, and then fill the region.
  5061. (save-restriction
  5062. (narrow-to-region
  5063. ;; Find the first line we should include in the region to fill.
  5064. (if start (progn (beginning-of-line) (point))
  5065. (save-excursion
  5066. (while (and (zerop (forward-line -1))
  5067. (looking-at "^[ \t]*#+[ \t]*[^ \t\n#]")))
  5068. ;; We may have gone to far. Go forward again.
  5069. (or (looking-at "^[ \t]*#+[ \t]*[^ \t\n#]")
  5070. (forward-line 1))
  5071. (point)))
  5072. ;; Find the beginning of the first line past the region to fill.
  5073. (save-excursion
  5074. (while (progn (forward-line 1)
  5075. (looking-at "^[ \t]*#+[ \t]*[^ \t\n#]")))
  5076. (point)))
  5077. ;; Remove existing hashes
  5078. (goto-char (point-min))
  5079. (save-excursion
  5080. (while (progn (forward-line 1) (< (point) (point-max)))
  5081. (skip-chars-forward " \t")
  5082. (if (looking-at "#+")
  5083. (progn
  5084. (if (and (eq (point) (match-beginning 0))
  5085. (not (eq (point) (match-end 0)))) nil
  5086. (error
  5087. "Bug in Emacs: `looking-at' in `narrow-to-region': match-data is garbage"))
  5088. (delete-char (- (match-end 0) (match-beginning 0)))))))
  5089. ;; Lines with only hashes on them can be paragraph boundaries.
  5090. (let ((paragraph-start (concat paragraph-start "\\|^[ \t#]*$"))
  5091. (paragraph-separate (concat paragraph-start "\\|^[ \t#]*$"))
  5092. (fill-prefix comment-fill-prefix))
  5093. (fill-paragraph justify)))
  5094. (if (and start)
  5095. (progn
  5096. (goto-char start)
  5097. (if (> dc 0)
  5098. (progn (delete-char dc) (insert spaces)))
  5099. (if (or (= (current-column) c) iteration) nil
  5100. (setq comment-column c)
  5101. (indent-for-comment)
  5102. ;; Repeat once more, flagging as iteration
  5103. (cperl-fill-paragraph justify t))))))
  5104. t)
  5105. (defun cperl-do-auto-fill ()
  5106. ;; Break out if the line is short enough
  5107. (if (> (save-excursion
  5108. (end-of-line)
  5109. (current-column))
  5110. fill-column)
  5111. (let ((c (save-excursion (beginning-of-line)
  5112. (cperl-to-comment-or-eol) (point)))
  5113. (s (memq (following-char) '(?\s ?\t))) marker)
  5114. (if (>= c (point))
  5115. ;; Don't break line inside code: only inside comment.
  5116. nil
  5117. (setq marker (point-marker))
  5118. (fill-paragraph nil)
  5119. (goto-char marker)
  5120. ;; Is not enough, sometimes marker is a start of line
  5121. (if (bolp) (progn (re-search-forward "#+[ \t]*")
  5122. (goto-char (match-end 0))))
  5123. ;; Following space could have gone:
  5124. (if (or (not s) (memq (following-char) '(?\s ?\t))) nil
  5125. (insert " ")
  5126. (backward-char 1))
  5127. ;; Previous space could have gone:
  5128. (or (memq (preceding-char) '(?\s ?\t)) (insert " "))))))
  5129. (defun cperl-imenu-addback (lst &optional isback name)
  5130. ;; We suppose that the lst is a DAG, unless the first element only
  5131. ;; loops back, and ISBACK is set. Thus this function cannot be
  5132. ;; applied twice without ISBACK set.
  5133. (cond ((not cperl-imenu-addback) lst)
  5134. (t
  5135. (or name
  5136. (setq name "+++BACK+++"))
  5137. (mapc (lambda (elt)
  5138. (if (and (listp elt) (listp (cdr elt)))
  5139. (progn
  5140. ;; In the other order it goes up
  5141. ;; one level only ;-(
  5142. (setcdr elt (cons (cons name lst)
  5143. (cdr elt)))
  5144. (cperl-imenu-addback (cdr elt) t name))))
  5145. (if isback (cdr lst) lst))
  5146. lst)))
  5147. (defun cperl-imenu--create-perl-index (&optional regexp)
  5148. (require 'imenu) ; May be called from TAGS creator
  5149. (let ((index-alist '()) (index-pack-alist '()) (index-pod-alist '())
  5150. (index-unsorted-alist '()) (i-s-f (default-value 'imenu-sort-function))
  5151. (index-meth-alist '()) meth
  5152. packages ends-ranges p marker is-proto
  5153. (prev-pos 0) is-pack index index1 name (end-range 0) package)
  5154. (goto-char (point-min))
  5155. (cperl-update-syntaxification (point-max) (point-max))
  5156. ;; Search for the function
  5157. (progn ;;save-match-data
  5158. (while (re-search-forward
  5159. (or regexp cperl-imenu--function-name-regexp-perl)
  5160. nil t)
  5161. ;; 2=package-group, 5=package-name 8=sub-name
  5162. (cond
  5163. ((and ; Skip some noise if building tags
  5164. (match-beginning 5) ; package name
  5165. ;;(eq (char-after (match-beginning 2)) ?p) ; package
  5166. (not (save-match-data
  5167. (looking-at "[ \t\n]*;")))) ; Plain text word 'package'
  5168. nil)
  5169. ((and
  5170. (or (match-beginning 2)
  5171. (match-beginning 8)) ; package or sub
  5172. ;; Skip if quoted (will not skip multi-line ''-strings :-():
  5173. (null (get-text-property (match-beginning 1) 'syntax-table))
  5174. (null (get-text-property (match-beginning 1) 'syntax-type))
  5175. (null (get-text-property (match-beginning 1) 'in-pod)))
  5176. (setq is-pack (match-beginning 2))
  5177. ;; (if (looking-at "([^()]*)[ \t\n\f]*")
  5178. ;; (goto-char (match-end 0))) ; Messes what follows
  5179. (setq meth nil
  5180. p (point))
  5181. (while (and ends-ranges (>= p (car ends-ranges)))
  5182. ;; delete obsolete entries
  5183. (setq ends-ranges (cdr ends-ranges) packages (cdr packages)))
  5184. (setq package (or (car packages) "")
  5185. end-range (or (car ends-ranges) 0))
  5186. (if is-pack ; doing "package"
  5187. (progn
  5188. (if (match-beginning 5) ; named package
  5189. (setq name (buffer-substring (match-beginning 5)
  5190. (match-end 5))
  5191. name (progn
  5192. (set-text-properties 0 (length name) nil name)
  5193. name)
  5194. package (concat name "::")
  5195. name (concat "package " name))
  5196. ;; Support nameless packages
  5197. (setq name "package;" package ""))
  5198. (setq end-range
  5199. (save-excursion
  5200. (parse-partial-sexp (point) (point-max) -1) (point))
  5201. ends-ranges (cons end-range ends-ranges)
  5202. packages (cons package packages)))
  5203. (setq is-proto
  5204. (or (eq (following-char) ?\;)
  5205. (eq 0 (get-text-property (point) 'attrib-group)))))
  5206. ;; Skip this function name if it is a prototype declaration.
  5207. (if (and is-proto (not is-pack)) nil
  5208. (or is-pack
  5209. (setq name
  5210. (buffer-substring (match-beginning 8) (match-end 8)))
  5211. (set-text-properties 0 (length name) nil name))
  5212. (setq marker (make-marker))
  5213. (set-marker marker (match-end (if is-pack 2 8)))
  5214. (cond (is-pack nil)
  5215. ((string-match "[:']" name)
  5216. (setq meth t))
  5217. ((> p end-range) nil)
  5218. (t
  5219. (setq name (concat package name) meth t)))
  5220. (setq index (cons name marker))
  5221. (if is-pack
  5222. (push index index-pack-alist)
  5223. (push index index-alist))
  5224. (if meth (push index index-meth-alist))
  5225. (push index index-unsorted-alist)))
  5226. ((match-beginning 16) ; POD section
  5227. (setq name (buffer-substring (match-beginning 17) (match-end 17))
  5228. marker (make-marker))
  5229. (set-marker marker (match-beginning 17))
  5230. (set-text-properties 0 (length name) nil name)
  5231. (setq name (concat (make-string
  5232. (* 3 (- (char-after (match-beginning 16)) ?1))
  5233. ?\ )
  5234. name)
  5235. index (cons name marker))
  5236. (setq index1 (cons (concat "=" name) (cdr index)))
  5237. (push index index-pod-alist)
  5238. (push index1 index-unsorted-alist)))))
  5239. (setq index-alist
  5240. (if (default-value 'imenu-sort-function)
  5241. (sort index-alist (default-value 'imenu-sort-function))
  5242. (nreverse index-alist)))
  5243. (and index-pod-alist
  5244. (push (cons "+POD headers+..."
  5245. (nreverse index-pod-alist))
  5246. index-alist))
  5247. (and (or index-pack-alist index-meth-alist)
  5248. (let ((lst index-pack-alist) hier-list pack elt group name)
  5249. ;; Remove "package ", reverse and uniquify.
  5250. (while lst
  5251. (setq elt (car lst) lst (cdr lst) name (substring (car elt) 8))
  5252. (if (assoc name hier-list) nil
  5253. (setq hier-list (cons (cons name (cdr elt)) hier-list))))
  5254. (setq lst index-meth-alist)
  5255. (while lst
  5256. (setq elt (car lst) lst (cdr lst))
  5257. (cond ((string-match "\\(::\\|'\\)[_a-zA-Z0-9]+$" (car elt))
  5258. (setq pack (substring (car elt) 0 (match-beginning 0)))
  5259. (if (setq group (assoc pack hier-list))
  5260. (if (listp (cdr group))
  5261. ;; Have some functions already
  5262. (setcdr group
  5263. (cons (cons (substring
  5264. (car elt)
  5265. (+ 2 (match-beginning 0)))
  5266. (cdr elt))
  5267. (cdr group)))
  5268. (setcdr group (list (cons (substring
  5269. (car elt)
  5270. (+ 2 (match-beginning 0)))
  5271. (cdr elt)))))
  5272. (setq hier-list
  5273. (cons (cons pack
  5274. (list (cons (substring
  5275. (car elt)
  5276. (+ 2 (match-beginning 0)))
  5277. (cdr elt))))
  5278. hier-list))))))
  5279. (push (cons "+Hierarchy+..."
  5280. hier-list)
  5281. index-alist)))
  5282. (and index-pack-alist
  5283. (push (cons "+Packages+..."
  5284. (nreverse index-pack-alist))
  5285. index-alist))
  5286. (and (or index-pack-alist index-pod-alist
  5287. (default-value 'imenu-sort-function))
  5288. index-unsorted-alist
  5289. (push (cons "+Unsorted List+..."
  5290. (nreverse index-unsorted-alist))
  5291. index-alist))
  5292. (cperl-imenu-addback index-alist)))
  5293. ;; Suggested by Mark A. Hershberger
  5294. (defun cperl-outline-level ()
  5295. (looking-at outline-regexp)
  5296. (cond ((not (match-beginning 1)) 0) ; beginning-of-file
  5297. ;;;; 2=package-group, 5=package-name 8=sub-name 16=head-level
  5298. ((match-beginning 2) 0) ; package
  5299. ((match-beginning 8) 1) ; sub
  5300. ((match-beginning 16)
  5301. (- (char-after (match-beginning 16)) ?0)) ; headN ==> N
  5302. (t 5))) ; should not happen
  5303. (defun cperl-windowed-init ()
  5304. "Initialization under windowed version."
  5305. (cond ((featurep 'ps-print)
  5306. (or cperl-faces-init
  5307. (progn
  5308. (and (boundp 'font-lock-multiline)
  5309. (setq cperl-font-lock-multiline t))
  5310. (cperl-init-faces))))
  5311. ((not cperl-faces-init)
  5312. (add-hook 'font-lock-mode-hook
  5313. (function
  5314. (lambda ()
  5315. (if (memq major-mode '(perl-mode cperl-mode))
  5316. (progn
  5317. (or cperl-faces-init (cperl-init-faces)))))))
  5318. (if (fboundp 'eval-after-load)
  5319. (eval-after-load
  5320. "ps-print"
  5321. '(or cperl-faces-init (cperl-init-faces)))))))
  5322. (defvar cperl-font-lock-keywords-1 nil
  5323. "Additional expressions to highlight in Perl mode. Minimal set.")
  5324. (defvar cperl-font-lock-keywords nil
  5325. "Additional expressions to highlight in Perl mode. Default set.")
  5326. (defvar cperl-font-lock-keywords-2 nil
  5327. "Additional expressions to highlight in Perl mode. Maximal set")
  5328. (defun cperl-load-font-lock-keywords ()
  5329. (or cperl-faces-init (cperl-init-faces))
  5330. cperl-font-lock-keywords)
  5331. (defun cperl-load-font-lock-keywords-1 ()
  5332. (or cperl-faces-init (cperl-init-faces))
  5333. cperl-font-lock-keywords-1)
  5334. (defun cperl-load-font-lock-keywords-2 ()
  5335. (or cperl-faces-init (cperl-init-faces))
  5336. cperl-font-lock-keywords-2)
  5337. (defun cperl-init-faces-weak ()
  5338. ;; Allow `cperl-find-pods-heres' to run.
  5339. (or (boundp 'font-lock-constant-face)
  5340. (cperl-force-face font-lock-constant-face
  5341. "Face for constant and label names"))
  5342. (or (boundp 'font-lock-warning-face)
  5343. (cperl-force-face font-lock-warning-face
  5344. "Face for things which should stand out"))
  5345. ;;(setq font-lock-constant-face 'font-lock-constant-face)
  5346. )
  5347. (defun cperl-init-faces ()
  5348. (condition-case errs
  5349. (progn
  5350. (require 'font-lock)
  5351. (and (fboundp 'font-lock-fontify-anchored-keywords)
  5352. (featurep 'font-lock-extra)
  5353. (message "You have an obsolete package `font-lock-extra'. Install `choose-color'."))
  5354. (let (t-font-lock-keywords t-font-lock-keywords-1 font-lock-anchored)
  5355. (if (fboundp 'font-lock-fontify-anchored-keywords)
  5356. (setq font-lock-anchored t))
  5357. (setq
  5358. t-font-lock-keywords
  5359. (list
  5360. `("[ \t]+$" 0 ',cperl-invalid-face t)
  5361. (cons
  5362. (concat
  5363. "\\(^\\|[^$@%&\\]\\)\\<\\("
  5364. (mapconcat
  5365. 'identity
  5366. '("if" "until" "while" "elsif" "else" "unless" "for"
  5367. "foreach" "continue" "exit" "die" "last" "goto" "next"
  5368. "redo" "return" "local" "exec" "sub" "do" "dump" "use" "our"
  5369. "require" "package" "eval" "my" "BEGIN" "END" "CHECK" "INIT")
  5370. "\\|") ; Flow control
  5371. "\\)\\>") 2) ; was "\\)[ \n\t;():,|&]"
  5372. ; In what follows we use `type' style
  5373. ; for overwritable builtins
  5374. (list
  5375. (concat
  5376. "\\(^\\|[^$@%&\\]\\)\\<\\("
  5377. ;; "CORE" "__FILE__" "__LINE__" "abs" "accept" "alarm"
  5378. ;; "and" "atan2" "bind" "binmode" "bless" "caller"
  5379. ;; "chdir" "chmod" "chown" "chr" "chroot" "close"
  5380. ;; "closedir" "cmp" "connect" "continue" "cos" "crypt"
  5381. ;; "dbmclose" "dbmopen" "die" "dump" "endgrent"
  5382. ;; "endhostent" "endnetent" "endprotoent" "endpwent"
  5383. ;; "endservent" "eof" "eq" "exec" "exit" "exp" "fcntl"
  5384. ;; "fileno" "flock" "fork" "formline" "ge" "getc"
  5385. ;; "getgrent" "getgrgid" "getgrnam" "gethostbyaddr"
  5386. ;; "gethostbyname" "gethostent" "getlogin"
  5387. ;; "getnetbyaddr" "getnetbyname" "getnetent"
  5388. ;; "getpeername" "getpgrp" "getppid" "getpriority"
  5389. ;; "getprotobyname" "getprotobynumber" "getprotoent"
  5390. ;; "getpwent" "getpwnam" "getpwuid" "getservbyname"
  5391. ;; "getservbyport" "getservent" "getsockname"
  5392. ;; "getsockopt" "glob" "gmtime" "gt" "hex" "index" "int"
  5393. ;; "ioctl" "join" "kill" "lc" "lcfirst" "le" "length"
  5394. ;; "link" "listen" "localtime" "lock" "log" "lstat" "lt"
  5395. ;; "mkdir" "msgctl" "msgget" "msgrcv" "msgsnd" "ne"
  5396. ;; "not" "oct" "open" "opendir" "or" "ord" "pack" "pipe"
  5397. ;; "quotemeta" "rand" "read" "readdir" "readline"
  5398. ;; "readlink" "readpipe" "recv" "ref" "rename" "require"
  5399. ;; "reset" "reverse" "rewinddir" "rindex" "rmdir" "seek"
  5400. ;; "seekdir" "select" "semctl" "semget" "semop" "send"
  5401. ;; "setgrent" "sethostent" "setnetent" "setpgrp"
  5402. ;; "setpriority" "setprotoent" "setpwent" "setservent"
  5403. ;; "setsockopt" "shmctl" "shmget" "shmread" "shmwrite"
  5404. ;; "shutdown" "sin" "sleep" "socket" "socketpair"
  5405. ;; "sprintf" "sqrt" "srand" "stat" "substr" "symlink"
  5406. ;; "syscall" "sysopen" "sysread" "system" "syswrite" "tell"
  5407. ;; "telldir" "time" "times" "truncate" "uc" "ucfirst"
  5408. ;; "umask" "unlink" "unpack" "utime" "values" "vec"
  5409. ;; "wait" "waitpid" "wantarray" "warn" "write" "x" "xor"
  5410. "a\\(bs\\|ccept\\|tan2\\|larm\\|nd\\)\\|"
  5411. "b\\(in\\(d\\|mode\\)\\|less\\)\\|"
  5412. "c\\(h\\(r\\(\\|oot\\)\\|dir\\|mod\\|own\\)\\|aller\\|rypt\\|"
  5413. "lose\\(\\|dir\\)\\|mp\\|o\\(s\\|n\\(tinue\\|nect\\)\\)\\)\\|"
  5414. "CORE\\|d\\(ie\\|bm\\(close\\|open\\)\\|ump\\)\\|"
  5415. "e\\(x\\(p\\|it\\|ec\\)\\|q\\|nd\\(p\\(rotoent\\|went\\)\\|"
  5416. "hostent\\|servent\\|netent\\|grent\\)\\|of\\)\\|"
  5417. "f\\(ileno\\|cntl\\|lock\\|or\\(k\\|mline\\)\\)\\|"
  5418. "g\\(t\\|lob\\|mtime\\|e\\(\\|t\\(p\\(pid\\|r\\(iority\\|"
  5419. "oto\\(byn\\(ame\\|umber\\)\\|ent\\)\\)\\|eername\\|w"
  5420. "\\(uid\\|ent\\|nam\\)\\|grp\\)\\|host\\(by\\(addr\\|name\\)\\|"
  5421. "ent\\)\\|s\\(erv\\(by\\(port\\|name\\)\\|ent\\)\\|"
  5422. "ock\\(name\\|opt\\)\\)\\|c\\|login\\|net\\(by\\(addr\\|name\\)\\|"
  5423. "ent\\)\\|gr\\(ent\\|nam\\|gid\\)\\)\\)\\)\\|"
  5424. "hex\\|i\\(n\\(t\\|dex\\)\\|octl\\)\\|join\\|kill\\|"
  5425. "l\\(i\\(sten\\|nk\\)\\|stat\\|c\\(\\|first\\)\\|t\\|e"
  5426. "\\(\\|ngth\\)\\|o\\(c\\(altime\\|k\\)\\|g\\)\\)\\|m\\(sg\\(rcv\\|snd\\|"
  5427. "ctl\\|get\\)\\|kdir\\)\\|n\\(e\\|ot\\)\\|o\\(pen\\(\\|dir\\)\\|"
  5428. "r\\(\\|d\\)\\|ct\\)\\|p\\(ipe\\|ack\\)\\|quotemeta\\|"
  5429. "r\\(index\\|and\\|mdir\\|e\\(quire\\|ad\\(pipe\\|\\|lin"
  5430. "\\(k\\|e\\)\\|dir\\)\\|set\\|cv\\|verse\\|f\\|winddir\\|name"
  5431. "\\)\\)\\|s\\(printf\\|qrt\\|rand\\|tat\\|ubstr\\|e\\(t\\(p\\(r"
  5432. "\\(iority\\|otoent\\)\\|went\\|grp\\)\\|hostent\\|s\\(ervent\\|"
  5433. "ockopt\\)\\|netent\\|grent\\)\\|ek\\(\\|dir\\)\\|lect\\|"
  5434. "m\\(ctl\\|op\\|get\\)\\|nd\\)\\|h\\(utdown\\|m\\(read\\|ctl\\|"
  5435. "write\\|get\\)\\)\\|y\\(s\\(read\\|call\\|open\\|tem\\|write\\)\\|"
  5436. "mlink\\)\\|in\\|leep\\|ocket\\(pair\\|\\)\\)\\|t\\(runcate\\|"
  5437. "ell\\(\\|dir\\)\\|ime\\(\\|s\\)\\)\\|u\\(c\\(\\|first\\)\\|"
  5438. "time\\|mask\\|n\\(pack\\|link\\)\\)\\|v\\(alues\\|ec\\)\\|"
  5439. "w\\(a\\(rn\\|it\\(pid\\|\\)\\|ntarray\\)\\|rite\\)\\|"
  5440. "x\\(\\|or\\)\\|__\\(FILE__\\|LINE__\\|PACKAGE__\\)"
  5441. "\\)\\>") 2 'font-lock-type-face)
  5442. ;; In what follows we use `other' style
  5443. ;; for nonoverwritable builtins
  5444. ;; Somehow 's', 'm' are not auto-generated???
  5445. (list
  5446. (concat
  5447. "\\(^\\|[^$@%&\\]\\)\\<\\("
  5448. ;; "AUTOLOAD" "BEGIN" "CHECK" "DESTROY" "END" "INIT" "__END__" "chomp"
  5449. ;; "chop" "defined" "delete" "do" "each" "else" "elsif"
  5450. ;; "eval" "exists" "for" "foreach" "format" "goto"
  5451. ;; "grep" "if" "keys" "last" "local" "map" "my" "next"
  5452. ;; "no" "our" "package" "pop" "pos" "print" "printf" "push"
  5453. ;; "q" "qq" "qw" "qx" "redo" "return" "scalar" "shift"
  5454. ;; "sort" "splice" "split" "study" "sub" "tie" "tr"
  5455. ;; "undef" "unless" "unshift" "untie" "until" "use"
  5456. ;; "while" "y"
  5457. "AUTOLOAD\\|BEGIN\\|CHECK\\|cho\\(p\\|mp\\)\\|d\\(e\\(fined\\|lete\\)\\|"
  5458. "o\\)\\|DESTROY\\|e\\(ach\\|val\\|xists\\|ls\\(e\\|if\\)\\)\\|"
  5459. "END\\|for\\(\\|each\\|mat\\)\\|g\\(rep\\|oto\\)\\|INIT\\|if\\|keys\\|"
  5460. "l\\(ast\\|ocal\\)\\|m\\(ap\\|y\\)\\|n\\(ext\\|o\\)\\|our\\|"
  5461. "p\\(ackage\\|rint\\(\\|f\\)\\|ush\\|o\\(p\\|s\\)\\)\\|"
  5462. "q\\(\\|q\\|w\\|x\\|r\\)\\|re\\(turn\\|do\\)\\|s\\(pli\\(ce\\|t\\)\\|"
  5463. "calar\\|tudy\\|ub\\|hift\\|ort\\)\\|t\\(r\\|ie\\)\\|"
  5464. "u\\(se\\|n\\(shift\\|ti\\(l\\|e\\)\\|def\\|less\\)\\)\\|"
  5465. "while\\|y\\|__\\(END\\|DATA\\)__" ;__DATA__ added manually
  5466. "\\|[sm]" ; Added manually
  5467. "\\)\\>") 2 'cperl-nonoverridable-face)
  5468. ;; (mapconcat 'identity
  5469. ;; '("#endif" "#else" "#ifdef" "#ifndef" "#if"
  5470. ;; "#include" "#define" "#undef")
  5471. ;; "\\|")
  5472. '("-[rwxoRWXOezsfdlpSbctugkTBMAC]\\>\\([ \t]+_\\>\\)?" 0
  5473. font-lock-function-name-face keep) ; Not very good, triggers at "[a-z]"
  5474. ;; This highlights declarations and definitions differently.
  5475. ;; We do not try to highlight in the case of attributes:
  5476. ;; it is already done by `cperl-find-pods-heres'
  5477. (list (concat "\\<sub"
  5478. cperl-white-and-comment-rex ; whitespace/comments
  5479. "\\([^ \n\t{;()]+\\)" ; 2=name (assume non-anonymous)
  5480. "\\("
  5481. cperl-maybe-white-and-comment-rex ;whitespace/comments?
  5482. "([^()]*)\\)?" ; prototype
  5483. cperl-maybe-white-and-comment-rex ; whitespace/comments?
  5484. "[{;]")
  5485. 2 (if cperl-font-lock-multiline
  5486. '(if (eq (char-after (cperl-1- (match-end 0))) ?\{ )
  5487. 'font-lock-function-name-face
  5488. 'font-lock-variable-name-face)
  5489. ;; need to manually set 'multiline' for older font-locks
  5490. '(progn
  5491. (if (< 1 (count-lines (match-beginning 0)
  5492. (match-end 0)))
  5493. (put-text-property
  5494. (+ 3 (match-beginning 0)) (match-end 0)
  5495. 'syntax-type 'multiline))
  5496. (if (eq (char-after (cperl-1- (match-end 0))) ?\{ )
  5497. 'font-lock-function-name-face
  5498. 'font-lock-variable-name-face))))
  5499. '("\\<\\(package\\|require\\|use\\|import\\|no\\|bootstrap\\)[ \t]+\\([a-zA-z_][a-zA-z_0-9:]*\\)[ \t;]" ; require A if B;
  5500. 2 font-lock-function-name-face)
  5501. '("^[ \t]*format[ \t]+\\([a-zA-z_][a-zA-z_0-9:]*\\)[ \t]*=[ \t]*$"
  5502. 1 font-lock-function-name-face)
  5503. (cond ((featurep 'font-lock-extra)
  5504. '("\\([]}\\\\%@>*&]\\|\\$[a-zA-Z0-9_:]*\\)[ \t]*{[ \t]*\\(-?[a-zA-Z0-9_:]+\\)[ \t]*}"
  5505. (2 font-lock-string-face t)
  5506. (0 '(restart 2 t)))) ; To highlight $a{bc}{ef}
  5507. (font-lock-anchored
  5508. '("\\([]}\\\\%@>*&]\\|\\$[a-zA-Z0-9_:]*\\)[ \t]*{[ \t]*\\(-?[a-zA-Z0-9_:]+\\)[ \t]*}"
  5509. (2 font-lock-string-face t)
  5510. ("\\=[ \t]*{[ \t]*\\(-?[a-zA-Z0-9_:]+\\)[ \t]*}"
  5511. nil nil
  5512. (1 font-lock-string-face t))))
  5513. (t '("\\([]}\\\\%@>*&]\\|\\$[a-zA-Z0-9_:]*\\)[ \t]*{[ \t]*\\(-?[a-zA-Z0-9_:]+\\)[ \t]*}"
  5514. 2 font-lock-string-face t)))
  5515. '("[[ \t{,(]\\(-?[a-zA-Z0-9_:]+\\)[ \t]*=>" 1
  5516. font-lock-string-face t)
  5517. '("^[ \t]*\\([a-zA-Z0-9_]+[ \t]*:\\)[ \t]*\\($\\|{\\|\\<\\(until\\|while\\|for\\(each\\)?\\|do\\)\\>\\)" 1
  5518. font-lock-constant-face) ; labels
  5519. '("\\<\\(continue\\|next\\|last\\|redo\\|goto\\)\\>[ \t]+\\([a-zA-Z0-9_:]+\\)" ; labels as targets
  5520. 2 font-lock-constant-face)
  5521. ;; Uncomment to get perl-mode-like vars
  5522. ;;; '("[$*]{?\\(\\sw+\\)" 1 font-lock-variable-name-face)
  5523. ;;; '("\\([@%]\\|\\$#\\)\\(\\sw+\\)"
  5524. ;;; (2 (cons font-lock-variable-name-face '(underline))))
  5525. (cond ((featurep 'font-lock-extra)
  5526. '("^[ \t]*\\(my\\|local\\|our\\)[ \t]*\\(([ \t]*\\)?\\([$@%*][a-zA-Z0-9_:]+\\)\\([ \t]*,\\)?"
  5527. (3 font-lock-variable-name-face)
  5528. (4 '(another 4 nil
  5529. ("\\=[ \t]*,[ \t]*\\([$@%*][a-zA-Z0-9_:]+\\)\\([ \t]*,\\)?"
  5530. (1 font-lock-variable-name-face)
  5531. (2 '(restart 2 nil) nil t)))
  5532. nil t))) ; local variables, multiple
  5533. (font-lock-anchored
  5534. ;; 1=my_etc, 2=white? 3=(+white? 4=white? 5=var
  5535. `(,(concat "\\<\\(my\\|local\\|our\\)"
  5536. cperl-maybe-white-and-comment-rex
  5537. "\\(("
  5538. cperl-maybe-white-and-comment-rex
  5539. "\\)?\\([$@%*]\\([a-zA-Z0-9_:]+\\|[^a-zA-Z0-9_]\\)\\)")
  5540. (5 ,(if cperl-font-lock-multiline
  5541. 'font-lock-variable-name-face
  5542. '(progn (setq cperl-font-lock-multiline-start
  5543. (match-beginning 0))
  5544. 'font-lock-variable-name-face)))
  5545. (,(concat "\\="
  5546. cperl-maybe-white-and-comment-rex
  5547. ","
  5548. cperl-maybe-white-and-comment-rex
  5549. "\\([$@%*]\\([a-zA-Z0-9_:]+\\|[^a-zA-Z0-9_]\\)\\)")
  5550. ;; Bug in font-lock: limit is used not only to limit
  5551. ;; searches, but to set the "extend window for
  5552. ;; facification" property. Thus we need to minimize.
  5553. ,(if cperl-font-lock-multiline
  5554. '(if (match-beginning 3)
  5555. (save-excursion
  5556. (goto-char (match-beginning 3))
  5557. (condition-case nil
  5558. (forward-sexp 1)
  5559. (error
  5560. (condition-case nil
  5561. (forward-char 200)
  5562. (error nil)))) ; typeahead
  5563. (1- (point))) ; report limit
  5564. (forward-char -2)) ; disable continued expr
  5565. '(if (match-beginning 3)
  5566. (point-max) ; No limit for continuation
  5567. (forward-char -2))) ; disable continued expr
  5568. ,(if cperl-font-lock-multiline
  5569. nil
  5570. '(progn ; Do at end
  5571. ;; "my" may be already fontified (POD),
  5572. ;; so cperl-font-lock-multiline-start is nil
  5573. (if (or (not cperl-font-lock-multiline-start)
  5574. (> 2 (count-lines
  5575. cperl-font-lock-multiline-start
  5576. (point))))
  5577. nil
  5578. (put-text-property
  5579. (1+ cperl-font-lock-multiline-start) (point)
  5580. 'syntax-type 'multiline))
  5581. (setq cperl-font-lock-multiline-start nil)))
  5582. (3 font-lock-variable-name-face))))
  5583. (t '("^[ \t{}]*\\(my\\|local\\|our\\)[ \t]*\\(([ \t]*\\)?\\([$@%*][a-zA-Z0-9_:]+\\)"
  5584. 3 font-lock-variable-name-face)))
  5585. '("\\<for\\(each\\)?\\([ \t]+\\(my\\|local\\|our\\)\\)?[ \t]*\\(\\$[a-zA-Z_][a-zA-Z_0-9]*\\)[ \t]*("
  5586. 4 font-lock-variable-name-face)
  5587. ;; Avoid $!, and s!!, qq!! etc. when not fontifying syntactically
  5588. '("\\(?:^\\|[^smywqrx$]\\)\\(!\\)" 1 font-lock-negation-char-face)
  5589. '("\\[\\(\\^\\)" 1 font-lock-negation-char-face prepend)))
  5590. (setq
  5591. t-font-lock-keywords-1
  5592. (and (fboundp 'turn-on-font-lock) ; Check for newer font-lock
  5593. ;; not yet as of XEmacs 19.12, works with 21.1.11
  5594. (or
  5595. (not (featurep 'xemacs))
  5596. (string< "21.1.9" emacs-version)
  5597. (and (string< "21.1.10" emacs-version)
  5598. (string< emacs-version "21.1.2")))
  5599. '(
  5600. ("\\(\\([@%]\\|\\$#\\)[a-zA-Z_:][a-zA-Z0-9_:]*\\)" 1
  5601. (if (eq (char-after (match-beginning 2)) ?%)
  5602. 'cperl-hash-face
  5603. 'cperl-array-face)
  5604. t) ; arrays and hashes
  5605. ("\\(\\([$@]+\\)[a-zA-Z_:][a-zA-Z0-9_:]*\\)[ \t]*\\([[{]\\)"
  5606. 1
  5607. (if (= (- (match-end 2) (match-beginning 2)) 1)
  5608. (if (eq (char-after (match-beginning 3)) ?{)
  5609. 'cperl-hash-face
  5610. 'cperl-array-face) ; arrays and hashes
  5611. font-lock-variable-name-face) ; Just to put something
  5612. t)
  5613. ("\\(@\\|\\$#\\)\\(\\$+\\([a-zA-Z_:][a-zA-Z0-9_:]*\\|[^ \t\n]\\)\\)"
  5614. (1 cperl-array-face)
  5615. (2 font-lock-variable-name-face))
  5616. ("\\(%\\)\\(\\$+\\([a-zA-Z_:][a-zA-Z0-9_:]*\\|[^ \t\n]\\)\\)"
  5617. (1 cperl-hash-face)
  5618. (2 font-lock-variable-name-face))
  5619. ;;("\\([smy]\\|tr\\)\\([^a-z_A-Z0-9]\\)\\(\\([^\n\\]*||\\)\\)\\2")
  5620. ;;; Too much noise from \s* @s[ and friends
  5621. ;;("\\(\\<\\([msy]\\|tr\\)[ \t]*\\([^ \t\na-zA-Z0-9_]\\)\\|\\(/\\)\\)"
  5622. ;;(3 font-lock-function-name-face t t)
  5623. ;;(4
  5624. ;; (if (cperl-slash-is-regexp)
  5625. ;; font-lock-function-name-face 'default) nil t))
  5626. )))
  5627. (if cperl-highlight-variables-indiscriminately
  5628. (setq t-font-lock-keywords-1
  5629. (append t-font-lock-keywords-1
  5630. (list '("\\([$*]{?\\sw+\\)" 1
  5631. font-lock-variable-name-face)))))
  5632. (setq cperl-font-lock-keywords-1
  5633. (if cperl-syntaxify-by-font-lock
  5634. (cons 'cperl-fontify-update
  5635. t-font-lock-keywords)
  5636. t-font-lock-keywords)
  5637. cperl-font-lock-keywords cperl-font-lock-keywords-1
  5638. cperl-font-lock-keywords-2 (append
  5639. cperl-font-lock-keywords-1
  5640. t-font-lock-keywords-1)))
  5641. (if (fboundp 'ps-print-buffer) (cperl-ps-print-init))
  5642. (if (or (featurep 'choose-color) (featurep 'font-lock-extra))
  5643. (eval ; Avoid a warning
  5644. '(font-lock-require-faces
  5645. (list
  5646. ;; Color-light Color-dark Gray-light Gray-dark Mono
  5647. (list 'font-lock-comment-face
  5648. ["Firebrick" "OrangeRed" "DimGray" "Gray80"]
  5649. nil
  5650. [nil nil t t t]
  5651. [nil nil t t t]
  5652. nil)
  5653. (list 'font-lock-string-face
  5654. ["RosyBrown" "LightSalmon" "Gray50" "LightGray"]
  5655. nil
  5656. nil
  5657. [nil nil t t t]
  5658. nil)
  5659. (list 'font-lock-function-name-face
  5660. (vector
  5661. "Blue" "LightSkyBlue" "Gray50" "LightGray"
  5662. (cdr (assq 'background-color ; if mono
  5663. (frame-parameters))))
  5664. (vector
  5665. nil nil nil nil
  5666. (cdr (assq 'foreground-color ; if mono
  5667. (frame-parameters))))
  5668. [nil nil t t t]
  5669. nil
  5670. nil)
  5671. (list 'font-lock-variable-name-face
  5672. ["DarkGoldenrod" "LightGoldenrod" "DimGray" "Gray90"]
  5673. nil
  5674. [nil nil t t t]
  5675. [nil nil t t t]
  5676. nil)
  5677. (list 'font-lock-type-face
  5678. ["DarkOliveGreen" "PaleGreen" "DimGray" "Gray80"]
  5679. nil
  5680. [nil nil t t t]
  5681. nil
  5682. [nil nil t t t])
  5683. (list 'font-lock-warning-face
  5684. ["Pink" "Red" "Gray50" "LightGray"]
  5685. ["gray20" "gray90"
  5686. "gray80" "gray20"]
  5687. [nil nil t t t]
  5688. nil
  5689. [nil nil t t t]
  5690. )
  5691. (list 'font-lock-constant-face
  5692. ["CadetBlue" "Aquamarine" "Gray50" "LightGray"]
  5693. nil
  5694. [nil nil t t t]
  5695. nil
  5696. [nil nil t t t])
  5697. (list 'cperl-nonoverridable-face
  5698. ["chartreuse3" ("orchid1" "orange")
  5699. nil "Gray80"]
  5700. [nil nil "gray90"]
  5701. [nil nil nil t t]
  5702. [nil nil t t]
  5703. [nil nil t t t])
  5704. (list 'cperl-array-face
  5705. ["blue" "yellow" nil "Gray80"]
  5706. ["lightyellow2" ("navy" "os2blue" "darkgreen")
  5707. "gray90"]
  5708. t
  5709. nil
  5710. nil)
  5711. (list 'cperl-hash-face
  5712. ["red" "red" nil "Gray80"]
  5713. ["lightyellow2" ("navy" "os2blue" "darkgreen")
  5714. "gray90"]
  5715. t
  5716. t
  5717. nil))))
  5718. ;; Do it the dull way, without choose-color
  5719. (defvar cperl-guessed-background nil
  5720. "Display characteristics as guessed by cperl.")
  5721. ;; (or (fboundp 'x-color-defined-p)
  5722. ;; (defalias 'x-color-defined-p
  5723. ;; (cond ((fboundp 'color-defined-p) 'color-defined-p)
  5724. ;; ;; XEmacs >= 19.12
  5725. ;; ((fboundp 'valid-color-name-p) 'valid-color-name-p)
  5726. ;; ;; XEmacs 19.11
  5727. ;; (t 'x-valid-color-name-p))))
  5728. (cperl-force-face font-lock-constant-face
  5729. "Face for constant and label names")
  5730. (cperl-force-face font-lock-variable-name-face
  5731. "Face for variable names")
  5732. (cperl-force-face font-lock-type-face
  5733. "Face for data types")
  5734. (cperl-force-face cperl-nonoverridable-face
  5735. "Face for data types from another group")
  5736. (cperl-force-face font-lock-warning-face
  5737. "Face for things which should stand out")
  5738. (cperl-force-face font-lock-comment-face
  5739. "Face for comments")
  5740. (cperl-force-face font-lock-function-name-face
  5741. "Face for function names")
  5742. (cperl-force-face cperl-hash-face
  5743. "Face for hashes")
  5744. (cperl-force-face cperl-array-face
  5745. "Face for arrays")
  5746. ;;(defvar font-lock-constant-face 'font-lock-constant-face)
  5747. ;;(defvar font-lock-variable-name-face 'font-lock-variable-name-face)
  5748. ;;(or (boundp 'font-lock-type-face)
  5749. ;; (defconst font-lock-type-face
  5750. ;; 'font-lock-type-face
  5751. ;; "Face to use for data types."))
  5752. ;;(or (boundp 'cperl-nonoverridable-face)
  5753. ;; (defconst cperl-nonoverridable-face
  5754. ;; 'cperl-nonoverridable-face
  5755. ;; "Face to use for data types from another group."))
  5756. ;;(if (not (featurep 'xemacs)) nil
  5757. ;; (or (boundp 'font-lock-comment-face)
  5758. ;; (defconst font-lock-comment-face
  5759. ;; 'font-lock-comment-face
  5760. ;; "Face to use for comments."))
  5761. ;; (or (boundp 'font-lock-keyword-face)
  5762. ;; (defconst font-lock-keyword-face
  5763. ;; 'font-lock-keyword-face
  5764. ;; "Face to use for keywords."))
  5765. ;; (or (boundp 'font-lock-function-name-face)
  5766. ;; (defconst font-lock-function-name-face
  5767. ;; 'font-lock-function-name-face
  5768. ;; "Face to use for function names.")))
  5769. (if (and
  5770. (not (cperl-is-face 'cperl-array-face))
  5771. (cperl-is-face 'font-lock-emphasized-face))
  5772. (copy-face 'font-lock-emphasized-face 'cperl-array-face))
  5773. (if (and
  5774. (not (cperl-is-face 'cperl-hash-face))
  5775. (cperl-is-face 'font-lock-other-emphasized-face))
  5776. (copy-face 'font-lock-other-emphasized-face 'cperl-hash-face))
  5777. (if (and
  5778. (not (cperl-is-face 'cperl-nonoverridable-face))
  5779. (cperl-is-face 'font-lock-other-type-face))
  5780. (copy-face 'font-lock-other-type-face 'cperl-nonoverridable-face))
  5781. ;;(or (boundp 'cperl-hash-face)
  5782. ;; (defconst cperl-hash-face
  5783. ;; 'cperl-hash-face
  5784. ;; "Face to use for hashes."))
  5785. ;;(or (boundp 'cperl-array-face)
  5786. ;; (defconst cperl-array-face
  5787. ;; 'cperl-array-face
  5788. ;; "Face to use for arrays."))
  5789. ;; Here we try to guess background
  5790. (let ((background
  5791. (if (boundp 'font-lock-background-mode)
  5792. font-lock-background-mode
  5793. 'light))
  5794. (face-list (and (fboundp 'face-list) (face-list))))
  5795. ;;;; (fset 'cperl-is-face
  5796. ;;;; (cond ((fboundp 'find-face)
  5797. ;;;; (symbol-function 'find-face))
  5798. ;;;; (face-list
  5799. ;;;; (function (lambda (face) (member face face-list))))
  5800. ;;;; (t
  5801. ;;;; (function (lambda (face) (boundp face))))))
  5802. (defvar cperl-guessed-background
  5803. (if (and (boundp 'font-lock-display-type)
  5804. (eq font-lock-display-type 'grayscale))
  5805. 'gray
  5806. background)
  5807. "Background as guessed by CPerl mode")
  5808. (and (not (cperl-is-face 'font-lock-constant-face))
  5809. (cperl-is-face 'font-lock-reference-face)
  5810. (copy-face 'font-lock-reference-face 'font-lock-constant-face))
  5811. (if (cperl-is-face 'font-lock-type-face) nil
  5812. (copy-face 'default 'font-lock-type-face)
  5813. (cond
  5814. ((eq background 'light)
  5815. (set-face-foreground 'font-lock-type-face
  5816. (if (x-color-defined-p "seagreen")
  5817. "seagreen"
  5818. "sea green")))
  5819. ((eq background 'dark)
  5820. (set-face-foreground 'font-lock-type-face
  5821. (if (x-color-defined-p "os2pink")
  5822. "os2pink"
  5823. "pink")))
  5824. (t
  5825. (set-face-background 'font-lock-type-face "gray90"))))
  5826. (if (cperl-is-face 'cperl-nonoverridable-face)
  5827. nil
  5828. (copy-face 'font-lock-type-face 'cperl-nonoverridable-face)
  5829. (cond
  5830. ((eq background 'light)
  5831. (set-face-foreground 'cperl-nonoverridable-face
  5832. (if (x-color-defined-p "chartreuse3")
  5833. "chartreuse3"
  5834. "chartreuse")))
  5835. ((eq background 'dark)
  5836. (set-face-foreground 'cperl-nonoverridable-face
  5837. (if (x-color-defined-p "orchid1")
  5838. "orchid1"
  5839. "orange")))))
  5840. ;;; (if (cperl-is-face 'font-lock-other-emphasized-face) nil
  5841. ;;; (copy-face 'bold-italic 'font-lock-other-emphasized-face)
  5842. ;;; (cond
  5843. ;;; ((eq background 'light)
  5844. ;;; (set-face-background 'font-lock-other-emphasized-face
  5845. ;;; (if (x-color-defined-p "lightyellow2")
  5846. ;;; "lightyellow2"
  5847. ;;; (if (x-color-defined-p "lightyellow")
  5848. ;;; "lightyellow"
  5849. ;;; "light yellow"))))
  5850. ;;; ((eq background 'dark)
  5851. ;;; (set-face-background 'font-lock-other-emphasized-face
  5852. ;;; (if (x-color-defined-p "navy")
  5853. ;;; "navy"
  5854. ;;; (if (x-color-defined-p "darkgreen")
  5855. ;;; "darkgreen"
  5856. ;;; "dark green"))))
  5857. ;;; (t (set-face-background 'font-lock-other-emphasized-face "gray90"))))
  5858. ;;; (if (cperl-is-face 'font-lock-emphasized-face) nil
  5859. ;;; (copy-face 'bold 'font-lock-emphasized-face)
  5860. ;;; (cond
  5861. ;;; ((eq background 'light)
  5862. ;;; (set-face-background 'font-lock-emphasized-face
  5863. ;;; (if (x-color-defined-p "lightyellow2")
  5864. ;;; "lightyellow2"
  5865. ;;; "lightyellow")))
  5866. ;;; ((eq background 'dark)
  5867. ;;; (set-face-background 'font-lock-emphasized-face
  5868. ;;; (if (x-color-defined-p "navy")
  5869. ;;; "navy"
  5870. ;;; (if (x-color-defined-p "darkgreen")
  5871. ;;; "darkgreen"
  5872. ;;; "dark green"))))
  5873. ;;; (t (set-face-background 'font-lock-emphasized-face "gray90"))))
  5874. (if (cperl-is-face 'font-lock-variable-name-face) nil
  5875. (copy-face 'italic 'font-lock-variable-name-face))
  5876. (if (cperl-is-face 'font-lock-constant-face) nil
  5877. (copy-face 'italic 'font-lock-constant-face))))
  5878. (setq cperl-faces-init t))
  5879. (error (message "cperl-init-faces (ignored): %s" errs))))
  5880. (defvar ps-bold-faces)
  5881. (defvar ps-italic-faces)
  5882. (defvar ps-underlined-faces)
  5883. (defun cperl-ps-print-init ()
  5884. "Initialization of `ps-print' components for faces used in CPerl."
  5885. (eval-after-load "ps-print"
  5886. '(setq ps-bold-faces
  5887. ;; font-lock-variable-name-face
  5888. ;; font-lock-constant-face
  5889. (append '(cperl-array-face cperl-hash-face)
  5890. ps-bold-faces)
  5891. ps-italic-faces
  5892. ;; font-lock-constant-face
  5893. (append '(cperl-nonoverridable-face cperl-hash-face)
  5894. ps-italic-faces)
  5895. ps-underlined-faces
  5896. ;; font-lock-type-face
  5897. (append '(cperl-array-face cperl-hash-face underline cperl-nonoverridable-face)
  5898. ps-underlined-faces))))
  5899. (defvar ps-print-face-extension-alist)
  5900. (defun cperl-ps-print (&optional file)
  5901. "Pretty-print in CPerl style.
  5902. If optional argument FILE is an empty string, prints to printer, otherwise
  5903. to the file FILE. If FILE is nil, prompts for a file name.
  5904. Style of printout regulated by the variable `cperl-ps-print-face-properties'."
  5905. (interactive)
  5906. (or file
  5907. (setq file (read-from-minibuffer
  5908. "Print to file (if empty - to printer): "
  5909. (concat (buffer-file-name) ".ps")
  5910. nil nil 'file-name-history)))
  5911. (or (> (length file) 0)
  5912. (setq file nil))
  5913. (require 'ps-print) ; To get ps-print-face-extension-alist
  5914. (let ((ps-print-color-p t)
  5915. (ps-print-face-extension-alist ps-print-face-extension-alist))
  5916. (cperl-ps-extend-face-list cperl-ps-print-face-properties)
  5917. (ps-print-buffer-with-faces file)))
  5918. ;;; (defun cperl-ps-print-init ()
  5919. ;;; "Initialization of `ps-print' components for faces used in CPerl."
  5920. ;;; ;; Guard against old versions
  5921. ;;; (defvar ps-underlined-faces nil)
  5922. ;;; (defvar ps-bold-faces nil)
  5923. ;;; (defvar ps-italic-faces nil)
  5924. ;;; (setq ps-bold-faces
  5925. ;;; (append '(font-lock-emphasized-face
  5926. ;;; cperl-array-face
  5927. ;;; font-lock-keyword-face
  5928. ;;; font-lock-variable-name-face
  5929. ;;; font-lock-constant-face
  5930. ;;; font-lock-reference-face
  5931. ;;; font-lock-other-emphasized-face
  5932. ;;; cperl-hash-face)
  5933. ;;; ps-bold-faces))
  5934. ;;; (setq ps-italic-faces
  5935. ;;; (append '(cperl-nonoverridable-face
  5936. ;;; font-lock-constant-face
  5937. ;;; font-lock-reference-face
  5938. ;;; font-lock-other-emphasized-face
  5939. ;;; cperl-hash-face)
  5940. ;;; ps-italic-faces))
  5941. ;;; (setq ps-underlined-faces
  5942. ;;; (append '(font-lock-emphasized-face
  5943. ;;; cperl-array-face
  5944. ;;; font-lock-other-emphasized-face
  5945. ;;; cperl-hash-face
  5946. ;;; cperl-nonoverridable-face font-lock-type-face)
  5947. ;;; ps-underlined-faces))
  5948. ;;; (cons 'font-lock-type-face ps-underlined-faces))
  5949. (if (cperl-enable-font-lock) (cperl-windowed-init))
  5950. (defconst cperl-styles-entries
  5951. '(cperl-indent-level cperl-brace-offset cperl-continued-brace-offset
  5952. cperl-label-offset cperl-extra-newline-before-brace
  5953. cperl-extra-newline-before-brace-multiline
  5954. cperl-merge-trailing-else
  5955. cperl-continued-statement-offset))
  5956. (defconst cperl-style-examples
  5957. "##### Numbers etc are: cperl-indent-level cperl-brace-offset
  5958. ##### cperl-continued-brace-offset cperl-label-offset
  5959. ##### cperl-continued-statement-offset
  5960. ##### cperl-merge-trailing-else cperl-extra-newline-before-brace
  5961. ########### (Do not forget cperl-extra-newline-before-brace-multiline)
  5962. ### CPerl (=GNU - extra-newline-before-brace + merge-trailing-else) 2/0/0/-2/2/t/nil
  5963. if (foo) {
  5964. bar
  5965. baz;
  5966. label:
  5967. {
  5968. boon;
  5969. }
  5970. } else {
  5971. stop;
  5972. }
  5973. ### PerlStyle (=CPerl with 4 as indent) 4/0/0/-4/4/t/nil
  5974. if (foo) {
  5975. bar
  5976. baz;
  5977. label:
  5978. {
  5979. boon;
  5980. }
  5981. } else {
  5982. stop;
  5983. }
  5984. ### GNU 2/0/0/-2/2/nil/t
  5985. if (foo)
  5986. {
  5987. bar
  5988. baz;
  5989. label:
  5990. {
  5991. boon;
  5992. }
  5993. }
  5994. else
  5995. {
  5996. stop;
  5997. }
  5998. ### C++ (=PerlStyle with braces aligned with control words) 4/0/-4/-4/4/nil/t
  5999. if (foo)
  6000. {
  6001. bar
  6002. baz;
  6003. label:
  6004. {
  6005. boon;
  6006. }
  6007. }
  6008. else
  6009. {
  6010. stop;
  6011. }
  6012. ### BSD (=C++, but will not change preexisting merge-trailing-else
  6013. ### and extra-newline-before-brace ) 4/0/-4/-4/4
  6014. if (foo)
  6015. {
  6016. bar
  6017. baz;
  6018. label:
  6019. {
  6020. boon;
  6021. }
  6022. }
  6023. else
  6024. {
  6025. stop;
  6026. }
  6027. ### K&R (=C++ with indent 5 - merge-trailing-else, but will not
  6028. ### change preexisting extra-newline-before-brace) 5/0/-5/-5/5/nil
  6029. if (foo)
  6030. {
  6031. bar
  6032. baz;
  6033. label:
  6034. {
  6035. boon;
  6036. }
  6037. }
  6038. else
  6039. {
  6040. stop;
  6041. }
  6042. ### Whitesmith (=PerlStyle, but will not change preexisting
  6043. ### extra-newline-before-brace and merge-trailing-else) 4/0/0/-4/4
  6044. if (foo)
  6045. {
  6046. bar
  6047. baz;
  6048. label:
  6049. {
  6050. boon;
  6051. }
  6052. }
  6053. else
  6054. {
  6055. stop;
  6056. }
  6057. "
  6058. "Examples of if/else with different indent styles (with v4.23).")
  6059. (defconst cperl-style-alist
  6060. '(("CPerl" ;; =GNU - extra-newline-before-brace + cperl-merge-trailing-else
  6061. (cperl-indent-level . 2)
  6062. (cperl-brace-offset . 0)
  6063. (cperl-continued-brace-offset . 0)
  6064. (cperl-label-offset . -2)
  6065. (cperl-continued-statement-offset . 2)
  6066. (cperl-extra-newline-before-brace . nil)
  6067. (cperl-extra-newline-before-brace-multiline . nil)
  6068. (cperl-merge-trailing-else . t))
  6069. ("PerlStyle" ; CPerl with 4 as indent
  6070. (cperl-indent-level . 4)
  6071. (cperl-brace-offset . 0)
  6072. (cperl-continued-brace-offset . 0)
  6073. (cperl-label-offset . -4)
  6074. (cperl-continued-statement-offset . 4)
  6075. (cperl-extra-newline-before-brace . nil)
  6076. (cperl-extra-newline-before-brace-multiline . nil)
  6077. (cperl-merge-trailing-else . t))
  6078. ("GNU"
  6079. (cperl-indent-level . 2)
  6080. (cperl-brace-offset . 0)
  6081. (cperl-continued-brace-offset . 0)
  6082. (cperl-label-offset . -2)
  6083. (cperl-continued-statement-offset . 2)
  6084. (cperl-extra-newline-before-brace . t)
  6085. (cperl-extra-newline-before-brace-multiline . t)
  6086. (cperl-merge-trailing-else . nil))
  6087. ("K&R"
  6088. (cperl-indent-level . 5)
  6089. (cperl-brace-offset . 0)
  6090. (cperl-continued-brace-offset . -5)
  6091. (cperl-label-offset . -5)
  6092. (cperl-continued-statement-offset . 5)
  6093. ;;(cperl-extra-newline-before-brace . nil) ; ???
  6094. ;;(cperl-extra-newline-before-brace-multiline . nil)
  6095. (cperl-merge-trailing-else . nil))
  6096. ("BSD"
  6097. (cperl-indent-level . 4)
  6098. (cperl-brace-offset . 0)
  6099. (cperl-continued-brace-offset . -4)
  6100. (cperl-label-offset . -4)
  6101. (cperl-continued-statement-offset . 4)
  6102. ;;(cperl-extra-newline-before-brace . nil) ; ???
  6103. ;;(cperl-extra-newline-before-brace-multiline . nil)
  6104. ;;(cperl-merge-trailing-else . nil) ; ???
  6105. )
  6106. ("C++"
  6107. (cperl-indent-level . 4)
  6108. (cperl-brace-offset . 0)
  6109. (cperl-continued-brace-offset . -4)
  6110. (cperl-label-offset . -4)
  6111. (cperl-continued-statement-offset . 4)
  6112. (cperl-extra-newline-before-brace . t)
  6113. (cperl-extra-newline-before-brace-multiline . t)
  6114. (cperl-merge-trailing-else . nil))
  6115. ("Whitesmith"
  6116. (cperl-indent-level . 4)
  6117. (cperl-brace-offset . 0)
  6118. (cperl-continued-brace-offset . 0)
  6119. (cperl-label-offset . -4)
  6120. (cperl-continued-statement-offset . 4)
  6121. ;;(cperl-extra-newline-before-brace . nil) ; ???
  6122. ;;(cperl-extra-newline-before-brace-multiline . nil)
  6123. ;;(cperl-merge-trailing-else . nil) ; ???
  6124. )
  6125. ("Current"))
  6126. "List of variables to set to get a particular indentation style.
  6127. Should be used via `cperl-set-style' or via Perl menu.
  6128. See examples in `cperl-style-examples'.")
  6129. (defun cperl-set-style (style)
  6130. "Set CPerl mode variables to use one of several different indentation styles.
  6131. The arguments are a string representing the desired style.
  6132. The list of styles is in `cperl-style-alist', available styles
  6133. are CPerl, PerlStyle, GNU, K&R, BSD, C++ and Whitesmith.
  6134. The current value of style is memorized (unless there is a memorized
  6135. data already), may be restored by `cperl-set-style-back'.
  6136. Choosing \"Current\" style will not change style, so this may be used for
  6137. side-effect of memorizing only. Examples in `cperl-style-examples'."
  6138. (interactive
  6139. (let ((list (mapcar (function (lambda (elt) (list (car elt))))
  6140. cperl-style-alist)))
  6141. (list (completing-read "Enter style: " list nil 'insist))))
  6142. (or cperl-old-style
  6143. (setq cperl-old-style
  6144. (mapcar (function
  6145. (lambda (name)
  6146. (cons name (eval name))))
  6147. cperl-styles-entries)))
  6148. (let ((style (cdr (assoc style cperl-style-alist))) setting str sym)
  6149. (while style
  6150. (setq setting (car style) style (cdr style))
  6151. (set (car setting) (cdr setting)))))
  6152. (defun cperl-set-style-back ()
  6153. "Restore a style memorized by `cperl-set-style'."
  6154. (interactive)
  6155. (or cperl-old-style (error "The style was not changed"))
  6156. (let (setting)
  6157. (while cperl-old-style
  6158. (setq setting (car cperl-old-style)
  6159. cperl-old-style (cdr cperl-old-style))
  6160. (set (car setting) (cdr setting)))))
  6161. (defun cperl-check-syntax ()
  6162. (interactive)
  6163. (require 'mode-compile)
  6164. (let ((perl-dbg-flags (concat cperl-extra-perl-args " -wc")))
  6165. (eval '(mode-compile)))) ; Avoid a warning
  6166. (declare-function Info-find-node "info"
  6167. (filename nodename &optional no-going-back strict-case))
  6168. (defun cperl-info-buffer (type)
  6169. ;; Returns buffer with documentation. Creates if missing.
  6170. ;; If TYPE, this vars buffer.
  6171. ;; Special care is taken to not stomp over an existing info buffer
  6172. (let* ((bname (if type "*info-perl-var*" "*info-perl*"))
  6173. (info (get-buffer bname))
  6174. (oldbuf (get-buffer "*info*")))
  6175. (if info info
  6176. (save-window-excursion
  6177. ;; Get Info running
  6178. (require 'info)
  6179. (cond (oldbuf
  6180. (set-buffer oldbuf)
  6181. (rename-buffer "*info-perl-tmp*")))
  6182. (save-window-excursion
  6183. (info))
  6184. (Info-find-node cperl-info-page (if type "perlvar" "perlfunc"))
  6185. (set-buffer "*info*")
  6186. (rename-buffer bname)
  6187. (cond (oldbuf
  6188. (set-buffer "*info-perl-tmp*")
  6189. (rename-buffer "*info*")
  6190. (set-buffer bname)))
  6191. (make-local-variable 'window-min-height)
  6192. (setq window-min-height 2)
  6193. (current-buffer)))))
  6194. (defun cperl-word-at-point (&optional p)
  6195. "Return the word at point or at P."
  6196. (save-excursion
  6197. (if p (goto-char p))
  6198. (or (cperl-word-at-point-hard)
  6199. (progn
  6200. (require 'etags)
  6201. (funcall (or (and (boundp 'find-tag-default-function)
  6202. find-tag-default-function)
  6203. (get major-mode 'find-tag-default-function)
  6204. ;; XEmacs 19.12 has `find-tag-default-hook'; it is
  6205. ;; automatically used within `find-tag-default':
  6206. 'find-tag-default))))))
  6207. (defun cperl-info-on-command (command)
  6208. "Show documentation for Perl command COMMAND in other window.
  6209. If perl-info buffer is shown in some frame, uses this frame.
  6210. Customized by setting variables `cperl-shrink-wrap-info-frame',
  6211. `cperl-max-help-size'."
  6212. (interactive
  6213. (let* ((default (cperl-word-at-point))
  6214. (read (read-string
  6215. (format "Find doc for Perl function (default %s): "
  6216. default))))
  6217. (list (if (equal read "")
  6218. default
  6219. read))))
  6220. (let ((buffer (current-buffer))
  6221. (cmd-desc (concat "^" (regexp-quote command) "[^a-zA-Z_0-9]")) ; "tr///"
  6222. pos isvar height iniheight frheight buf win fr1 fr2 iniwin not-loner
  6223. max-height char-height buf-list)
  6224. (if (string-match "^-[a-zA-Z]$" command)
  6225. (setq cmd-desc "^-X[ \t\n]"))
  6226. (setq isvar (string-match "^[$@%]" command)
  6227. buf (cperl-info-buffer isvar)
  6228. iniwin (selected-window)
  6229. fr1 (window-frame iniwin))
  6230. (set-buffer buf)
  6231. (goto-char (point-min))
  6232. (or isvar
  6233. (progn (re-search-forward "^-X[ \t\n]")
  6234. (forward-line -1)))
  6235. (if (re-search-forward cmd-desc nil t)
  6236. (progn
  6237. ;; Go back to beginning of the group (ex, for qq)
  6238. (if (re-search-backward "^[ \t\n\f]")
  6239. (forward-line 1))
  6240. (beginning-of-line)
  6241. ;; Get some of
  6242. (setq pos (point)
  6243. buf-list (list buf "*info-perl-var*" "*info-perl*"))
  6244. (while (and (not win) buf-list)
  6245. (setq win (get-buffer-window (car buf-list) t))
  6246. (setq buf-list (cdr buf-list)))
  6247. (or (not win)
  6248. (eq (window-buffer win) buf)
  6249. (set-window-buffer win buf))
  6250. (and win (setq fr2 (window-frame win)))
  6251. (if (or (not fr2) (eq fr1 fr2))
  6252. (pop-to-buffer buf)
  6253. (special-display-popup-frame buf) ; Make it visible
  6254. (select-window win))
  6255. (goto-char pos) ; Needed (?!).
  6256. ;; Resize
  6257. (setq iniheight (window-height)
  6258. frheight (frame-height)
  6259. not-loner (< iniheight (1- frheight))) ; Are not alone
  6260. (cond ((if not-loner cperl-max-help-size
  6261. cperl-shrink-wrap-info-frame)
  6262. (setq height
  6263. (+ 2
  6264. (count-lines
  6265. pos
  6266. (save-excursion
  6267. (if (re-search-forward
  6268. "^[ \t][^\n]*\n+\\([^ \t\n\f]\\|\\'\\)" nil t)
  6269. (match-beginning 0) (point-max)))))
  6270. max-height
  6271. (if not-loner
  6272. (/ (* (- frheight 3) cperl-max-help-size) 100)
  6273. (setq char-height (frame-char-height))
  6274. ;; Non-functioning under OS/2:
  6275. (if (eq char-height 1) (setq char-height 18))
  6276. ;; Title, menubar, + 2 for slack
  6277. (- (/ (display-pixel-height) char-height) 4)))
  6278. (if (> height max-height) (setq height max-height))
  6279. ;;(message "was %s doing %s" iniheight height)
  6280. (if not-loner
  6281. (enlarge-window (- height iniheight))
  6282. (set-frame-height (window-frame win) (1+ height)))))
  6283. (set-window-start (selected-window) pos))
  6284. (message "No entry for %s found." command))
  6285. ;;(pop-to-buffer buffer)
  6286. (select-window iniwin)))
  6287. (defun cperl-info-on-current-command ()
  6288. "Show documentation for Perl command at point in other window."
  6289. (interactive)
  6290. (cperl-info-on-command (cperl-word-at-point)))
  6291. (defun cperl-imenu-info-imenu-search ()
  6292. (if (looking-at "^-X[ \t\n]") nil
  6293. (re-search-backward
  6294. "^\n\\([-a-zA-Z_]+\\)[ \t\n]")
  6295. (forward-line 1)))
  6296. (defun cperl-imenu-info-imenu-name ()
  6297. (buffer-substring
  6298. (match-beginning 1) (match-end 1)))
  6299. (declare-function imenu-choose-buffer-index "imenu" (&optional prompt alist))
  6300. (defun cperl-imenu-on-info ()
  6301. "Shows imenu for Perl Info Buffer.
  6302. Opens Perl Info buffer if needed."
  6303. (interactive)
  6304. (require 'imenu)
  6305. (let* ((buffer (current-buffer))
  6306. imenu-create-index-function
  6307. imenu-prev-index-position-function
  6308. imenu-extract-index-name-function
  6309. (index-item (save-restriction
  6310. (save-window-excursion
  6311. (set-buffer (cperl-info-buffer nil))
  6312. (setq imenu-create-index-function
  6313. 'imenu-default-create-index-function
  6314. imenu-prev-index-position-function
  6315. 'cperl-imenu-info-imenu-search
  6316. imenu-extract-index-name-function
  6317. 'cperl-imenu-info-imenu-name)
  6318. (imenu-choose-buffer-index)))))
  6319. (and index-item
  6320. (progn
  6321. (push-mark)
  6322. (pop-to-buffer "*info-perl*")
  6323. (cond
  6324. ((markerp (cdr index-item))
  6325. (goto-char (marker-position (cdr index-item))))
  6326. (t
  6327. (goto-char (cdr index-item))))
  6328. (set-window-start (selected-window) (point))
  6329. (pop-to-buffer buffer)))))
  6330. (defun cperl-lineup (beg end &optional step minshift)
  6331. "Lineup construction in a region.
  6332. Beginning of region should be at the start of a construction.
  6333. All first occurrences of this construction in the lines that are
  6334. partially contained in the region are lined up at the same column.
  6335. MINSHIFT is the minimal amount of space to insert before the construction.
  6336. STEP is the tabwidth to position constructions.
  6337. If STEP is nil, `cperl-lineup-step' will be used
  6338. \(or `cperl-indent-level', if `cperl-lineup-step' is nil).
  6339. Will not move the position at the start to the left."
  6340. (interactive "r")
  6341. (let (search col tcol seen b)
  6342. (save-excursion
  6343. (goto-char end)
  6344. (end-of-line)
  6345. (setq end (point-marker))
  6346. (goto-char beg)
  6347. (skip-chars-forward " \t\f")
  6348. (setq beg (point-marker))
  6349. (indent-region beg end nil)
  6350. (goto-char beg)
  6351. (setq col (current-column))
  6352. (if (looking-at "[a-zA-Z0-9_]")
  6353. (if (looking-at "\\<[a-zA-Z0-9_]+\\>")
  6354. (setq search
  6355. (concat "\\<"
  6356. (regexp-quote
  6357. (buffer-substring (match-beginning 0)
  6358. (match-end 0))) "\\>"))
  6359. (error "Cannot line up in a middle of the word"))
  6360. (if (looking-at "$")
  6361. (error "Cannot line up end of line"))
  6362. (setq search (regexp-quote (char-to-string (following-char)))))
  6363. (setq step (or step cperl-lineup-step cperl-indent-level))
  6364. (or minshift (setq minshift 1))
  6365. (while (progn
  6366. (beginning-of-line 2)
  6367. (and (< (point) end)
  6368. (re-search-forward search end t)
  6369. (goto-char (match-beginning 0))))
  6370. (setq tcol (current-column) seen t)
  6371. (if (> tcol col) (setq col tcol)))
  6372. (or seen
  6373. (error "The construction to line up occurred only once"))
  6374. (goto-char beg)
  6375. (setq col (+ col minshift))
  6376. (if (/= (% col step) 0) (setq step (* step (1+ (/ col step)))))
  6377. (while
  6378. (progn
  6379. (cperl-make-indent col)
  6380. (beginning-of-line 2)
  6381. (and (< (point) end)
  6382. (re-search-forward search end t)
  6383. (goto-char (match-beginning 0)))))))) ; No body
  6384. (defun cperl-etags (&optional add all files) ;; NOT USED???
  6385. "Run etags with appropriate options for Perl files.
  6386. If optional argument ALL is `recursive', will process Perl files
  6387. in subdirectories too."
  6388. (interactive)
  6389. (let ((cmd "etags")
  6390. (args '("-l" "none" "-r"
  6391. ;; 1=fullname 2=package? 3=name 4=proto? 5=attrs? (VERY APPROX!)
  6392. "/\\<sub[ \\t]+\\(\\([a-zA-Z0-9:_]*::\\)?\\([a-zA-Z0-9_]+\\)\\)[ \\t]*\\(([^()]*)[ \t]*\\)?\\([ \t]*:[^#{;]*\\)?\\([{#]\\|$\\)/\\3/"
  6393. "-r"
  6394. "/\\<package[ \\t]+\\(\\([a-zA-Z0-9:_]*::\\)?\\([a-zA-Z0-9_]+\\)\\)[ \\t]*\\([#;]\\|$\\)/\\1/"
  6395. "-r"
  6396. "/\\<\\(package\\)[ \\t]*;/\\1;/"))
  6397. res)
  6398. (if add (setq args (cons "-a" args)))
  6399. (or files (setq files (list buffer-file-name)))
  6400. (cond
  6401. ((eq all 'recursive)
  6402. ;;(error "Not implemented: recursive")
  6403. (setq args (append (list "-e"
  6404. "sub wanted {push @ARGV, $File::Find::name if /\\.[pP][Llm]$/}
  6405. use File::Find;
  6406. find(\\&wanted, '.');
  6407. exec @ARGV;"
  6408. cmd) args)
  6409. cmd "perl"))
  6410. (all
  6411. ;;(error "Not implemented: all")
  6412. (setq args (append (list "-e"
  6413. "push @ARGV, <*.PL *.pl *.pm>;
  6414. exec @ARGV;"
  6415. cmd) args)
  6416. cmd "perl"))
  6417. (t
  6418. (setq args (append args files))))
  6419. (setq res (apply 'call-process cmd nil nil nil args))
  6420. (or (eq res 0)
  6421. (message "etags returned \"%s\"" res))))
  6422. (defun cperl-toggle-auto-newline ()
  6423. "Toggle the state of `cperl-auto-newline'."
  6424. (interactive)
  6425. (setq cperl-auto-newline (not cperl-auto-newline))
  6426. (message "Newlines will %sbe auto-inserted now."
  6427. (if cperl-auto-newline "" "not ")))
  6428. (defun cperl-toggle-abbrev ()
  6429. "Toggle the state of automatic keyword expansion in CPerl mode."
  6430. (interactive)
  6431. (abbrev-mode (if abbrev-mode 0 1))
  6432. (message "Perl control structure will %sbe auto-inserted now."
  6433. (if abbrev-mode "" "not ")))
  6434. (defun cperl-toggle-electric ()
  6435. "Toggle the state of parentheses doubling in CPerl mode."
  6436. (interactive)
  6437. (setq cperl-electric-parens (if (cperl-val 'cperl-electric-parens) 'null t))
  6438. (message "Parentheses will %sbe auto-doubled now."
  6439. (if (cperl-val 'cperl-electric-parens) "" "not ")))
  6440. (defun cperl-toggle-autohelp ()
  6441. "Toggle the state of Auto-Help on Perl constructs (put in the message area).
  6442. Delay of auto-help controlled by `cperl-lazy-help-time'."
  6443. (interactive)
  6444. (if (fboundp 'run-with-idle-timer)
  6445. (progn
  6446. (if cperl-lazy-installed
  6447. (cperl-lazy-unstall)
  6448. (cperl-lazy-install))
  6449. (message "Perl help messages will %sbe automatically shown now."
  6450. (if cperl-lazy-installed "" "not ")))
  6451. (message "Cannot automatically show Perl help messages - run-with-idle-timer missing.")))
  6452. (defun cperl-toggle-construct-fix ()
  6453. "Toggle whether `indent-region'/`indent-sexp' fix whitespace too."
  6454. (interactive)
  6455. (setq cperl-indent-region-fix-constructs
  6456. (if cperl-indent-region-fix-constructs
  6457. nil
  6458. 1))
  6459. (message "indent-region/indent-sexp will %sbe automatically fix whitespace."
  6460. (if cperl-indent-region-fix-constructs "" "not ")))
  6461. (defun cperl-toggle-set-debug-unwind (arg &optional backtrace)
  6462. "Toggle (or, with numeric argument, set) debugging state of syntaxification.
  6463. Nonpositive numeric argument disables debugging messages. The message
  6464. summarizes which regions it was decided to rescan for syntactic constructs.
  6465. The message looks like this:
  6466. Syxify req=123..138 actual=101..146 done-to: 112=>146 statepos: 73=>117
  6467. Numbers are character positions in the buffer. REQ provides the range to
  6468. rescan requested by `font-lock'. ACTUAL is the range actually resyntaxified;
  6469. for correct operation it should start and end outside any special syntactic
  6470. construct. DONE-TO and STATEPOS indicate changes to internal caches maintained
  6471. by CPerl."
  6472. (interactive "P")
  6473. (or arg
  6474. (setq arg (if (eq cperl-syntaxify-by-font-lock
  6475. (if backtrace 'backtrace 'message)) 0 1)))
  6476. (setq arg (if (> arg 0) (if backtrace 'backtrace 'message) t))
  6477. (setq cperl-syntaxify-by-font-lock arg)
  6478. (message "Debugging messages of syntax unwind %sabled."
  6479. (if (eq arg t) "dis" "en")))
  6480. ;;;; Tags file creation.
  6481. (defvar cperl-tmp-buffer " *cperl-tmp*")
  6482. (defun cperl-setup-tmp-buf ()
  6483. (set-buffer (get-buffer-create cperl-tmp-buffer))
  6484. (set-syntax-table cperl-mode-syntax-table)
  6485. (buffer-disable-undo)
  6486. (auto-fill-mode 0)
  6487. (if cperl-use-syntax-table-text-property-for-tags
  6488. (progn
  6489. (make-local-variable 'parse-sexp-lookup-properties)
  6490. ;; Do not introduce variable if not needed, we check it!
  6491. (set 'parse-sexp-lookup-properties t))))
  6492. ;; Copied from imenu-example--name-and-position.
  6493. (defvar imenu-use-markers)
  6494. (defun cperl-imenu-name-and-position ()
  6495. "Return the current/previous sexp and its (beginning) location.
  6496. Does not move point."
  6497. (save-excursion
  6498. (forward-sexp -1)
  6499. (let ((beg (if imenu-use-markers (point-marker) (point)))
  6500. (end (progn (forward-sexp) (point))))
  6501. (cons (buffer-substring beg end)
  6502. beg))))
  6503. (defun cperl-xsub-scan ()
  6504. (require 'imenu)
  6505. (let ((index-alist '())
  6506. (prev-pos 0) index index1 name package prefix)
  6507. (goto-char (point-min))
  6508. ;; Search for the function
  6509. (progn ;;save-match-data
  6510. (while (re-search-forward
  6511. "^\\([ \t]*MODULE\\>[^\n]*\\<PACKAGE[ \t]*=[ \t]*\\([a-zA-Z_][a-zA-Z_0-9:]*\\)\\>\\|\\([a-zA-Z_][a-zA-Z_0-9]*\\)(\\|[ \t]*BOOT:\\)"
  6512. nil t)
  6513. (cond
  6514. ((match-beginning 2) ; SECTION
  6515. (setq package (buffer-substring (match-beginning 2) (match-end 2)))
  6516. (goto-char (match-beginning 0))
  6517. (skip-chars-forward " \t")
  6518. (forward-char 1)
  6519. (if (looking-at "[^\n]*\\<PREFIX[ \t]*=[ \t]*\\([a-zA-Z_][a-zA-Z_0-9]*\\)\\>")
  6520. (setq prefix (buffer-substring (match-beginning 1) (match-end 1)))
  6521. (setq prefix nil)))
  6522. ((not package) nil) ; C language section
  6523. ((match-beginning 3) ; XSUB
  6524. (goto-char (1+ (match-beginning 3)))
  6525. (setq index (cperl-imenu-name-and-position))
  6526. (setq name (buffer-substring (match-beginning 3) (match-end 3)))
  6527. (if (and prefix (string-match (concat "^" prefix) name))
  6528. (setq name (substring name (length prefix))))
  6529. (cond ((string-match "::" name) nil)
  6530. (t
  6531. (setq index1 (cons (concat package "::" name) (cdr index)))
  6532. (push index1 index-alist)))
  6533. (setcar index name)
  6534. (push index index-alist))
  6535. (t ; BOOT: section
  6536. ;; (beginning-of-line)
  6537. (setq index (cperl-imenu-name-and-position))
  6538. (setcar index (concat package "::BOOT:"))
  6539. (push index index-alist)))))
  6540. index-alist))
  6541. (defvar cperl-unreadable-ok nil)
  6542. (defun cperl-find-tags (ifile xs topdir)
  6543. (let ((b (get-buffer cperl-tmp-buffer)) ind lst elt pos ret rel
  6544. (cperl-pod-here-fontify nil) f file)
  6545. (save-excursion
  6546. (if b (set-buffer b)
  6547. (cperl-setup-tmp-buf))
  6548. (erase-buffer)
  6549. (condition-case err
  6550. (setq file (car (insert-file-contents ifile)))
  6551. (error (if cperl-unreadable-ok nil
  6552. (if (y-or-n-p
  6553. (format "File %s unreadable. Continue? " ifile))
  6554. (setq cperl-unreadable-ok t)
  6555. (error "Aborting: unreadable file %s" ifile)))))
  6556. (if (not file)
  6557. (message "Unreadable file %s" ifile)
  6558. (message "Scanning file %s ..." file)
  6559. (if (and cperl-use-syntax-table-text-property-for-tags
  6560. (not xs))
  6561. (condition-case err ; after __END__ may have garbage
  6562. (cperl-find-pods-heres nil nil noninteractive)
  6563. (error (message "While scanning for syntax: %s" err))))
  6564. (if xs
  6565. (setq lst (cperl-xsub-scan))
  6566. (setq ind (cperl-imenu--create-perl-index))
  6567. (setq lst (cdr (assoc "+Unsorted List+..." ind))))
  6568. (setq lst
  6569. (mapcar
  6570. (function
  6571. (lambda (elt)
  6572. (cond ((string-match "^[_a-zA-Z]" (car elt))
  6573. (goto-char (cdr elt))
  6574. (beginning-of-line) ; pos should be of the start of the line
  6575. (list (car elt)
  6576. (point)
  6577. (1+ (count-lines 1 (point))) ; 1+ since at beg-o-l
  6578. (buffer-substring (progn
  6579. (goto-char (cdr elt))
  6580. ;; After name now...
  6581. (or (eolp) (forward-char 1))
  6582. (point))
  6583. (progn
  6584. (beginning-of-line)
  6585. (point))))))))
  6586. lst))
  6587. (erase-buffer)
  6588. (while lst
  6589. (setq elt (car lst) lst (cdr lst))
  6590. (if elt
  6591. (progn
  6592. (insert (elt elt 3)
  6593. 127
  6594. (if (string-match "^package " (car elt))
  6595. (substring (car elt) 8)
  6596. (car elt) )
  6597. 1
  6598. (number-to-string (elt elt 2)) ; Line
  6599. ","
  6600. (number-to-string (1- (elt elt 1))) ; Char pos 0-based
  6601. "\n")
  6602. (if (and (string-match "^[_a-zA-Z]+::" (car elt))
  6603. (string-match "^sub[ \t]+\\([_a-zA-Z]+\\)[^:_a-zA-Z]"
  6604. (elt elt 3)))
  6605. ;; Need to insert the name without package as well
  6606. (setq lst (cons (cons (substring (elt elt 3)
  6607. (match-beginning 1)
  6608. (match-end 1))
  6609. (cdr elt))
  6610. lst))))))
  6611. (setq pos (point))
  6612. (goto-char 1)
  6613. (setq rel file)
  6614. ;; On case-preserving filesystems (EMX on OS/2) case might be encoded in properties
  6615. (set-text-properties 0 (length rel) nil rel)
  6616. (and (equal topdir (substring rel 0 (length topdir)))
  6617. (setq rel (substring file (length topdir))))
  6618. (insert "\f\n" rel "," (number-to-string (1- pos)) "\n")
  6619. (setq ret (buffer-substring 1 (point-max)))
  6620. (erase-buffer)
  6621. (or noninteractive
  6622. (message "Scanning file %s finished" file))
  6623. ret))))
  6624. (defun cperl-add-tags-recurse-noxs ()
  6625. "Add to TAGS data for \"pure\" 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-noxs
  6629. "
  6630. (cperl-write-tags nil nil t t nil t))
  6631. (defun cperl-add-tags-recurse-noxs-fullpath ()
  6632. "Add to TAGS data for \"pure\" Perl in the current directory and kids.
  6633. Writes down fullpath, so TAGS is relocatable (but if the build directory
  6634. is relocated, the file TAGS inside it breaks). Use as
  6635. emacs -batch -q -no-site-file -l emacs/cperl-mode.el \
  6636. -f cperl-add-tags-recurse-noxs-fullpath
  6637. "
  6638. (cperl-write-tags nil nil t t nil t ""))
  6639. (defun cperl-add-tags-recurse ()
  6640. "Add to TAGS file data for Perl files in the current directory and kids.
  6641. Use as
  6642. emacs -batch -q -no-site-file -l emacs/cperl-mode.el \
  6643. -f cperl-add-tags-recurse
  6644. "
  6645. (cperl-write-tags nil nil t t))
  6646. (defun cperl-write-tags (&optional file erase recurse dir inbuffer noxs topdir)
  6647. ;; If INBUFFER, do not select buffer, and do not save
  6648. ;; If ERASE is `ignore', do not erase, and do not try to delete old info.
  6649. (require 'etags)
  6650. (if file nil
  6651. (setq file (if dir default-directory (buffer-file-name)))
  6652. (if (and (not dir) (buffer-modified-p)) (error "Save buffer first!")))
  6653. (or topdir
  6654. (setq topdir default-directory))
  6655. (let ((tags-file-name "TAGS")
  6656. (case-fold-search (and (featurep 'xemacs) (eq system-type 'emx)))
  6657. xs rel tm)
  6658. (save-excursion
  6659. (cond (inbuffer nil) ; Already there
  6660. ((file-exists-p tags-file-name)
  6661. (if (featurep 'xemacs)
  6662. (visit-tags-table-buffer)
  6663. (visit-tags-table-buffer tags-file-name)))
  6664. (t (set-buffer (find-file-noselect tags-file-name))))
  6665. (cond
  6666. (dir
  6667. (cond ((eq erase 'ignore))
  6668. (erase
  6669. (erase-buffer)
  6670. (setq erase 'ignore)))
  6671. (let ((files
  6672. (condition-case err
  6673. (directory-files file t
  6674. (if recurse nil cperl-scan-files-regexp)
  6675. t)
  6676. (error
  6677. (if cperl-unreadable-ok nil
  6678. (if (y-or-n-p
  6679. (format "Directory %s unreadable. Continue? " file))
  6680. (setq cperl-unreadable-ok t
  6681. tm nil) ; Return empty list
  6682. (error "Aborting: unreadable directory %s" file)))))))
  6683. (mapc (function
  6684. (lambda (file)
  6685. (cond
  6686. ((string-match cperl-noscan-files-regexp file)
  6687. nil)
  6688. ((not (file-directory-p file))
  6689. (if (string-match cperl-scan-files-regexp file)
  6690. (cperl-write-tags file erase recurse nil t noxs topdir)))
  6691. ((not recurse) nil)
  6692. (t (cperl-write-tags file erase recurse t t noxs topdir)))))
  6693. files)))
  6694. (t
  6695. (setq xs (string-match "\\.xs$" file))
  6696. (if (not (and xs noxs))
  6697. (progn
  6698. (cond ((eq erase 'ignore) (goto-char (point-max)))
  6699. (erase (erase-buffer))
  6700. (t
  6701. (goto-char 1)
  6702. (setq rel file)
  6703. ;; On case-preserving filesystems (EMX on OS/2) case might be encoded in properties
  6704. (set-text-properties 0 (length rel) nil rel)
  6705. (and (equal topdir (substring rel 0 (length topdir)))
  6706. (setq rel (substring file (length topdir))))
  6707. (if (search-forward (concat "\f\n" rel ",") nil t)
  6708. (progn
  6709. (search-backward "\f\n")
  6710. (delete-region (point)
  6711. (save-excursion
  6712. (forward-char 1)
  6713. (if (search-forward "\f\n"
  6714. nil 'toend)
  6715. (- (point) 2)
  6716. (point-max)))))
  6717. (goto-char (point-max)))))
  6718. (insert (cperl-find-tags file xs topdir))))))
  6719. (if inbuffer nil ; Delegate to the caller
  6720. (save-buffer 0) ; No backup
  6721. (if (fboundp 'initialize-new-tags-table) ; Do we need something special in XEmacs?
  6722. (initialize-new-tags-table))))))
  6723. (defvar cperl-tags-hier-regexp-list
  6724. (concat
  6725. "^\\("
  6726. "\\(package\\)\\>"
  6727. "\\|"
  6728. "sub\\>[^\n]+::"
  6729. "\\|"
  6730. "[a-zA-Z_][a-zA-Z_0-9:]*(\C-?[^\n]+::" ; XSUB?
  6731. "\\|"
  6732. "[ \t]*BOOT:\C-?[^\n]+::" ; BOOT section
  6733. "\\)"))
  6734. (defvar cperl-hierarchy '(() ())
  6735. "Global hierarchy of classes.")
  6736. ;; Follows call to (autoloaded) visit-tags-table.
  6737. (declare-function file-of-tag "etags" (&optional relative))
  6738. (declare-function etags-snarf-tag "etags" (&optional use-explicit))
  6739. (defun cperl-tags-hier-fill ()
  6740. ;; Suppose we are in a tag table cooked by cperl.
  6741. (goto-char 1)
  6742. (let (type pack name pos line chunk ord cons1 file str info fileind)
  6743. (while (re-search-forward cperl-tags-hier-regexp-list nil t)
  6744. (setq pos (match-beginning 0)
  6745. pack (match-beginning 2))
  6746. (beginning-of-line)
  6747. (if (looking-at (concat
  6748. "\\([^\n]+\\)"
  6749. "\C-?"
  6750. "\\([^\n]+\\)"
  6751. "\C-a"
  6752. "\\([0-9]+\\)"
  6753. ","
  6754. "\\([0-9]+\\)"))
  6755. (progn
  6756. (setq ;;str (buffer-substring (match-beginning 1) (match-end 1))
  6757. name (buffer-substring (match-beginning 2) (match-end 2))
  6758. ;;pos (buffer-substring (match-beginning 3) (match-end 3))
  6759. line (buffer-substring (match-beginning 3) (match-end 3))
  6760. ord (if pack 1 0)
  6761. file (file-of-tag)
  6762. fileind (format "%s:%s" file line)
  6763. ;; Moves to beginning of the next line:
  6764. info (cperl-etags-snarf-tag file line))
  6765. ;; Move back
  6766. (forward-char -1)
  6767. ;; Make new member of hierarchy name ==> file ==> pos if needed
  6768. (if (setq cons1 (assoc name (nth ord cperl-hierarchy)))
  6769. ;; Name known
  6770. (setcdr cons1 (cons (cons fileind (vector file info))
  6771. (cdr cons1)))
  6772. ;; First occurrence of the name, start alist
  6773. (setq cons1 (cons name (list (cons fileind (vector file info)))))
  6774. (if pack
  6775. (setcar (cdr cperl-hierarchy)
  6776. (cons cons1 (nth 1 cperl-hierarchy)))
  6777. (setcar cperl-hierarchy
  6778. (cons cons1 (car cperl-hierarchy)))))))
  6779. (end-of-line))))
  6780. (declare-function x-popup-menu "menu.c" (position menu))
  6781. (declare-function etags-goto-tag-location "etags" (tag-info))
  6782. (defun cperl-tags-hier-init (&optional update)
  6783. "Show hierarchical menu of classes and methods.
  6784. Finds info about classes by a scan of loaded TAGS files.
  6785. Supposes that the TAGS files contain fully qualified function names.
  6786. One may build such TAGS files from CPerl mode menu."
  6787. (interactive)
  6788. (require 'etags)
  6789. (require 'imenu)
  6790. (if (or update (null (nth 2 cperl-hierarchy)))
  6791. (let ((remover (function (lambda (elt) ; (name (file1...) (file2..))
  6792. (or (nthcdr 2 elt)
  6793. ;; Only in one file
  6794. (setcdr elt (cdr (nth 1 elt)))))))
  6795. pack name cons1 to l1 l2 l3 l4 b)
  6796. ;; (setq cperl-hierarchy '(() () ())) ; Would write into '() later!
  6797. (setq cperl-hierarchy (list l1 l2 l3))
  6798. (if (featurep 'xemacs) ; Not checked
  6799. (progn
  6800. (or tags-file-name
  6801. ;; Does this work in XEmacs?
  6802. (call-interactively 'visit-tags-table))
  6803. (message "Updating list of classes...")
  6804. (set-buffer (get-file-buffer tags-file-name))
  6805. (cperl-tags-hier-fill))
  6806. (or tags-table-list
  6807. (call-interactively 'visit-tags-table))
  6808. (mapc
  6809. (function
  6810. (lambda (tagsfile)
  6811. (message "Updating list of classes... %s" tagsfile)
  6812. (set-buffer (get-file-buffer tagsfile))
  6813. (cperl-tags-hier-fill)))
  6814. tags-table-list)
  6815. (message "Updating list of classes... postprocessing..."))
  6816. (mapc remover (car cperl-hierarchy))
  6817. (mapc remover (nth 1 cperl-hierarchy))
  6818. (setq to (list nil (cons "Packages: " (nth 1 cperl-hierarchy))
  6819. (cons "Methods: " (car cperl-hierarchy))))
  6820. (cperl-tags-treeify to 1)
  6821. (setcar (nthcdr 2 cperl-hierarchy)
  6822. (cperl-menu-to-keymap (cons '("+++UPDATE+++" . -999) (cdr to))))
  6823. (message "Updating list of classes: done, requesting display...")
  6824. ;;(cperl-imenu-addback (nth 2 cperl-hierarchy))
  6825. ))
  6826. (or (nth 2 cperl-hierarchy)
  6827. (error "No items found"))
  6828. (setq update
  6829. ;;; (imenu-choose-buffer-index "Packages: " (nth 2 cperl-hierarchy))
  6830. (if (if (fboundp 'display-popup-menus-p)
  6831. (let ((f 'display-popup-menus-p))
  6832. (funcall f))
  6833. window-system)
  6834. (x-popup-menu t (nth 2 cperl-hierarchy))
  6835. (require 'tmm)
  6836. (tmm-prompt (nth 2 cperl-hierarchy))))
  6837. (if (and update (listp update))
  6838. (progn (while (cdr update) (setq update (cdr update)))
  6839. (setq update (car update)))) ; Get the last from the list
  6840. (if (vectorp update)
  6841. (progn
  6842. (find-file (elt update 0))
  6843. (cperl-etags-goto-tag-location (elt update 1))))
  6844. (if (eq update -999) (cperl-tags-hier-init t)))
  6845. (defun cperl-tags-treeify (to level)
  6846. ;; cadr of `to' is read-write. On start it is a cons
  6847. (let* ((regexp (concat "^\\(" (mapconcat
  6848. 'identity
  6849. (make-list level "[_a-zA-Z0-9]+")
  6850. "::")
  6851. "\\)\\(::\\)?"))
  6852. (packages (cdr (nth 1 to)))
  6853. (methods (cdr (nth 2 to)))
  6854. l1 head tail cons1 cons2 ord writeto packs recurse
  6855. root-packages root-functions ms many_ms same_name ps
  6856. (move-deeper
  6857. (function
  6858. (lambda (elt)
  6859. (cond ((and (string-match regexp (car elt))
  6860. (or (eq ord 1) (match-end 2)))
  6861. (setq head (substring (car elt) 0 (match-end 1))
  6862. tail (if (match-end 2) (substring (car elt)
  6863. (match-end 2)))
  6864. recurse t)
  6865. (if (setq cons1 (assoc head writeto)) nil
  6866. ;; Need to init new head
  6867. (setcdr writeto (cons (list head (list "Packages: ")
  6868. (list "Methods: "))
  6869. (cdr writeto)))
  6870. (setq cons1 (nth 1 writeto)))
  6871. (setq cons2 (nth ord cons1)) ; Either packs or meths
  6872. (setcdr cons2 (cons elt (cdr cons2))))
  6873. ((eq ord 2)
  6874. (setq root-functions (cons elt root-functions)))
  6875. (t
  6876. (setq root-packages (cons elt root-packages))))))))
  6877. (setcdr to l1) ; Init to dynamic space
  6878. (setq writeto to)
  6879. (setq ord 1)
  6880. (mapc move-deeper packages)
  6881. (setq ord 2)
  6882. (mapc move-deeper methods)
  6883. (if recurse
  6884. (mapc (function (lambda (elt)
  6885. (cperl-tags-treeify elt (1+ level))))
  6886. (cdr to)))
  6887. ;;Now clean up leaders with one child only
  6888. (mapc (function (lambda (elt)
  6889. (if (not (and (listp (cdr elt))
  6890. (eq (length elt) 2))) nil
  6891. (setcar elt (car (nth 1 elt)))
  6892. (setcdr elt (cdr (nth 1 elt))))))
  6893. (cdr to))
  6894. ;; Sort the roots of subtrees
  6895. (if (default-value 'imenu-sort-function)
  6896. (setcdr to
  6897. (sort (cdr to) (default-value 'imenu-sort-function))))
  6898. ;; Now add back functions removed from display
  6899. (mapc (function (lambda (elt)
  6900. (setcdr to (cons elt (cdr to)))))
  6901. (if (default-value 'imenu-sort-function)
  6902. (nreverse
  6903. (sort root-functions (default-value 'imenu-sort-function)))
  6904. root-functions))
  6905. ;; Now add back packages removed from display
  6906. (mapc (function (lambda (elt)
  6907. (setcdr to (cons (cons (concat "package " (car elt))
  6908. (cdr elt))
  6909. (cdr to)))))
  6910. (if (default-value 'imenu-sort-function)
  6911. (nreverse
  6912. (sort root-packages (default-value 'imenu-sort-function)))
  6913. root-packages))))
  6914. ;;;(x-popup-menu t
  6915. ;;; '(keymap "Name1"
  6916. ;;; ("Ret1" "aa")
  6917. ;;; ("Head1" "ab"
  6918. ;;; keymap "Name2"
  6919. ;;; ("Tail1" "x") ("Tail2" "y"))))
  6920. (defun cperl-list-fold (list name limit)
  6921. (let (list1 list2 elt1 (num 0))
  6922. (if (<= (length list) limit) list
  6923. (setq list1 nil list2 nil)
  6924. (while list
  6925. (setq num (1+ num)
  6926. elt1 (car list)
  6927. list (cdr list))
  6928. (if (<= num imenu-max-items)
  6929. (setq list2 (cons elt1 list2))
  6930. (setq list1 (cons (cons name
  6931. (nreverse list2))
  6932. list1)
  6933. list2 (list elt1)
  6934. num 1)))
  6935. (nreverse (cons (cons name
  6936. (nreverse list2))
  6937. list1)))))
  6938. (defun cperl-menu-to-keymap (menu &optional name)
  6939. (let (list)
  6940. (cons 'keymap
  6941. (mapcar
  6942. (function
  6943. (lambda (elt)
  6944. (cond ((listp (cdr elt))
  6945. (setq list (cperl-list-fold
  6946. (cdr elt) (car elt) imenu-max-items))
  6947. (cons nil
  6948. (cons (car elt)
  6949. (cperl-menu-to-keymap list))))
  6950. (t
  6951. (list (cdr elt) (car elt) t))))) ; t is needed in 19.34
  6952. (cperl-list-fold menu "Root" imenu-max-items)))))
  6953. (defvar cperl-bad-style-regexp
  6954. (mapconcat 'identity
  6955. '("[^-\n\t <>=+!.&|(*/'`\"#^][-=+<>!|&^]" ; char sign
  6956. "[-<>=+^&|]+[^- \t\n=+<>~]") ; sign+ char
  6957. "\\|")
  6958. "Finds places such that insertion of a whitespace may help a lot.")
  6959. (defvar cperl-not-bad-style-regexp
  6960. (mapconcat
  6961. 'identity
  6962. '("[^-\t <>=+]\\(--\\|\\+\\+\\)" ; var-- var++
  6963. "[a-zA-Z0-9_][|&][a-zA-Z0-9_$]" ; abc|def abc&def are often used.
  6964. "&[(a-zA-Z0-9_$]" ; &subroutine &(var->field)
  6965. "<\\$?\\sw+\\(\\.\\(\\sw\\|_\\)+\\)?>" ; <IN> <stdin.h>
  6966. "-[a-zA-Z][ \t]+[_$\"'`a-zA-Z]" ; -f file, -t STDIN
  6967. "-[0-9]" ; -5
  6968. "\\+\\+" ; ++var
  6969. "--" ; --var
  6970. ".->" ; a->b
  6971. "->" ; a SPACE ->b
  6972. "\\[-" ; a[-1]
  6973. "\\\\[&$@*\\\\]" ; \&func
  6974. "^=" ; =head
  6975. "\\$." ; $|
  6976. "<<[a-zA-Z_'\"`]" ; <<FOO, <<'FOO'
  6977. "||"
  6978. "&&"
  6979. "[CBIXSLFZ]<\\(\\sw\\|\\s \\|\\s_\\|[\n]\\)*>" ; C<code like text>
  6980. "-[a-zA-Z_0-9]+[ \t]*=>" ; -option => value
  6981. ;; Unaddressed trouble spots: = -abc, f(56, -abc) --- specialcased below
  6982. ;;"[*/+-|&<.]+="
  6983. )
  6984. "\\|")
  6985. "If matches at the start of match found by `my-bad-c-style-regexp',
  6986. insertion of a whitespace will not help.")
  6987. (defvar found-bad)
  6988. (defun cperl-find-bad-style ()
  6989. "Find places in the buffer where insertion of a whitespace may help.
  6990. Prompts user for insertion of spaces.
  6991. Currently it is tuned to C and Perl syntax."
  6992. (interactive)
  6993. (let (found-bad (p (point)))
  6994. (setq last-nonmenu-event 13) ; To disable popup
  6995. (goto-char (point-min))
  6996. (map-y-or-n-p "Insert space here? "
  6997. (lambda (arg) (insert " "))
  6998. 'cperl-next-bad-style
  6999. '("location" "locations" "insert a space into")
  7000. '((?\C-r (lambda (arg)
  7001. (let ((buffer-quit-function
  7002. 'exit-recursive-edit))
  7003. (message "Exit with Esc Esc")
  7004. (recursive-edit)
  7005. t)) ; Consider acted upon
  7006. "edit, exit with Esc Esc")
  7007. (?e (lambda (arg)
  7008. (let ((buffer-quit-function
  7009. 'exit-recursive-edit))
  7010. (message "Exit with Esc Esc")
  7011. (recursive-edit)
  7012. t)) ; Consider acted upon
  7013. "edit, exit with Esc Esc"))
  7014. t)
  7015. (if found-bad (goto-char found-bad)
  7016. (goto-char p)
  7017. (message "No appropriate place found"))))
  7018. (defun cperl-next-bad-style ()
  7019. (let (p (not-found t) (point (point)) found)
  7020. (while (and not-found
  7021. (re-search-forward cperl-bad-style-regexp nil 'to-end))
  7022. (setq p (point))
  7023. (goto-char (match-beginning 0))
  7024. (if (or
  7025. (looking-at cperl-not-bad-style-regexp)
  7026. ;; Check for a < -b and friends
  7027. (and (eq (following-char) ?\-)
  7028. (save-excursion
  7029. (skip-chars-backward " \t\n")
  7030. (memq (preceding-char) '(?\= ?\> ?\< ?\, ?\( ?\[ ?\{))))
  7031. ;; Now check for syntax type
  7032. (save-match-data
  7033. (setq found (point))
  7034. (beginning-of-defun)
  7035. (let ((pps (parse-partial-sexp (point) found)))
  7036. (or (nth 3 pps) (nth 4 pps) (nth 5 pps)))))
  7037. (goto-char (match-end 0))
  7038. (goto-char (1- p))
  7039. (setq not-found nil
  7040. found-bad found)))
  7041. (not not-found)))
  7042. ;;; Getting help
  7043. (defvar cperl-have-help-regexp
  7044. ;;(concat "\\("
  7045. (mapconcat
  7046. 'identity
  7047. '("[$@%*&][0-9a-zA-Z_:]+\\([ \t]*[[{]\\)?" ; Usual variable
  7048. "[$@]\\^[a-zA-Z]" ; Special variable
  7049. "[$@][^ \n\t]" ; Special variable
  7050. "-[a-zA-Z]" ; File test
  7051. "\\\\[a-zA-Z0]" ; Special chars
  7052. "^=[a-z][a-zA-Z0-9_]*" ; POD sections
  7053. "[-!&*+,-./<=>?\\\\^|~]+" ; Operator
  7054. "[a-zA-Z_0-9:]+" ; symbol or number
  7055. "x="
  7056. "#!")
  7057. ;;"\\)\\|\\("
  7058. "\\|")
  7059. ;;"\\)"
  7060. ;;)
  7061. "Matches places in the buffer we can find help for.")
  7062. (defvar cperl-message-on-help-error t)
  7063. (defvar cperl-help-from-timer nil)
  7064. (defun cperl-word-at-point-hard ()
  7065. ;; Does not save-excursion
  7066. ;; Get to the something meaningful
  7067. (or (eobp) (eolp) (forward-char 1))
  7068. (re-search-backward "[-a-zA-Z0-9_:!&*+,-./<=>?\\\\^|~$%@]"
  7069. (point-at-bol)
  7070. 'to-beg)
  7071. ;; (cond
  7072. ;; ((or (eobp) (looking-at "[][ \t\n{}();,]")) ; Not at a symbol
  7073. ;; (skip-chars-backward " \n\t\r({[]});,")
  7074. ;; (or (bobp) (backward-char 1))))
  7075. ;; Try to backtrace
  7076. (cond
  7077. ((looking-at "[a-zA-Z0-9_:]") ; symbol
  7078. (skip-chars-backward "a-zA-Z0-9_:")
  7079. (cond
  7080. ((and (eq (preceding-char) ?^) ; $^I
  7081. (eq (char-after (- (point) 2)) ?\$))
  7082. (forward-char -2))
  7083. ((memq (preceding-char) (append "*$@%&\\" nil)) ; *glob
  7084. (forward-char -1))
  7085. ((and (eq (preceding-char) ?\=)
  7086. (eq (current-column) 1))
  7087. (forward-char -1))) ; =head1
  7088. (if (and (eq (preceding-char) ?\<)
  7089. (looking-at "\\$?[a-zA-Z0-9_:]+>")) ; <FH>
  7090. (forward-char -1)))
  7091. ((and (looking-at "=") (eq (preceding-char) ?x)) ; x=
  7092. (forward-char -1))
  7093. ((and (looking-at "\\^") (eq (preceding-char) ?\$)) ; $^I
  7094. (forward-char -1))
  7095. ((looking-at "[-!&*+,-./<=>?\\\\^|~]")
  7096. (skip-chars-backward "-!&*+,-./<=>?\\\\^|~")
  7097. (cond
  7098. ((and (eq (preceding-char) ?\$)
  7099. (not (eq (char-after (- (point) 2)) ?\$))) ; $-
  7100. (forward-char -1))
  7101. ((and (eq (following-char) ?\>)
  7102. (string-match "[a-zA-Z0-9_]" (char-to-string (preceding-char)))
  7103. (save-excursion
  7104. (forward-sexp -1)
  7105. (and (eq (preceding-char) ?\<)
  7106. (looking-at "\\$?[a-zA-Z0-9_:]+>")))) ; <FH>
  7107. (search-backward "<"))))
  7108. ((and (eq (following-char) ?\$)
  7109. (eq (preceding-char) ?\<)
  7110. (looking-at "\\$?[a-zA-Z0-9_:]+>")) ; <$fh>
  7111. (forward-char -1)))
  7112. (if (looking-at cperl-have-help-regexp)
  7113. (buffer-substring (match-beginning 0) (match-end 0))))
  7114. (defun cperl-get-help ()
  7115. "Get one-line docs on the symbol at the point.
  7116. The data for these docs is a little bit obsolete and may be in fact longer
  7117. than a line. Your contribution to update/shorten it is appreciated."
  7118. (interactive)
  7119. (save-match-data ; May be called "inside" query-replace
  7120. (save-excursion
  7121. (let ((word (cperl-word-at-point-hard)))
  7122. (if word
  7123. (if (and cperl-help-from-timer ; Bail out if not in mainland
  7124. (not (string-match "^#!\\|\\\\\\|^=" word)) ; Show help even in comments/strings.
  7125. (or (memq (get-text-property (point) 'face)
  7126. '(font-lock-comment-face font-lock-string-face))
  7127. (memq (get-text-property (point) 'syntax-type)
  7128. '(pod here-doc format))))
  7129. nil
  7130. (cperl-describe-perl-symbol word))
  7131. (if cperl-message-on-help-error
  7132. (message "Nothing found for %s..."
  7133. (buffer-substring (point) (min (+ 5 (point)) (point-max))))))))))
  7134. ;;; Stolen from perl-descr.el by Johan Vromans:
  7135. (defvar cperl-doc-buffer " *perl-doc*"
  7136. "Where the documentation can be found.")
  7137. (defun cperl-describe-perl-symbol (val)
  7138. "Display the documentation of symbol at point, a Perl operator."
  7139. (let ((enable-recursive-minibuffers t)
  7140. args-file regexp)
  7141. (cond
  7142. ((string-match "^[&*][a-zA-Z_]" val)
  7143. (setq val (concat (substring val 0 1) "NAME")))
  7144. ((string-match "^[$@]\\([a-zA-Z_:0-9]+\\)[ \t]*\\[" val)
  7145. (setq val (concat "@" (substring val 1 (match-end 1)))))
  7146. ((string-match "^[$@]\\([a-zA-Z_:0-9]+\\)[ \t]*{" val)
  7147. (setq val (concat "%" (substring val 1 (match-end 1)))))
  7148. ((and (string= val "x") (string-match "^x=" val))
  7149. (setq val "x="))
  7150. ((string-match "^\\$[\C-a-\C-z]" val)
  7151. (setq val (concat "$^" (char-to-string (+ ?A -1 (aref val 1))))))
  7152. ((string-match "^CORE::" val)
  7153. (setq val "CORE::"))
  7154. ((string-match "^SUPER::" val)
  7155. (setq val "SUPER::"))
  7156. ((and (string= "<" val) (string-match "^<\\$?[a-zA-Z0-9_:]+>" val))
  7157. (setq val "<NAME>")))
  7158. (setq regexp (concat "^"
  7159. "\\([^a-zA-Z0-9_:]+[ \t]+\\)?"
  7160. (regexp-quote val)
  7161. "\\([ \t([/]\\|$\\)"))
  7162. ;; get the buffer with the documentation text
  7163. (cperl-switch-to-doc-buffer)
  7164. ;; lookup in the doc
  7165. (goto-char (point-min))
  7166. (let ((case-fold-search nil))
  7167. (list
  7168. (if (re-search-forward regexp (point-max) t)
  7169. (save-excursion
  7170. (beginning-of-line 1)
  7171. (let ((lnstart (point)))
  7172. (end-of-line)
  7173. (message "%s" (buffer-substring lnstart (point)))))
  7174. (if cperl-message-on-help-error
  7175. (message "No definition for %s" val)))))))
  7176. (defvar cperl-short-docs 'please-ignore-this-line
  7177. ;; Perl4 version was written by Johan Vromans (jvromans@squirrel.nl)
  7178. "# based on \\='@(#)@ perl-descr.el 1.9 - describe-perl-symbol\\=' [Perl 5]
  7179. ... Range (list context); flip/flop [no flop when flip] (scalar context).
  7180. ! ... Logical negation.
  7181. ... != ... Numeric inequality.
  7182. ... !~ ... Search pattern, substitution, or translation (negated).
  7183. $! In numeric context: errno. In a string context: error string.
  7184. $\" The separator which joins elements of arrays interpolated in strings.
  7185. $# The output format for printed numbers. Default is %.15g or close.
  7186. $$ Process number of this script. Changes in the fork()ed child process.
  7187. $% The current page number of the currently selected output channel.
  7188. The following variables are always local to the current block:
  7189. $1 Match of the 1st set of parentheses in the last match (auto-local).
  7190. $2 Match of the 2nd set of parentheses in the last match (auto-local).
  7191. $3 Match of the 3rd set of parentheses in the last match (auto-local).
  7192. $4 Match of the 4th set of parentheses in the last match (auto-local).
  7193. $5 Match of the 5th set of parentheses in the last match (auto-local).
  7194. $6 Match of the 6th set of parentheses in the last match (auto-local).
  7195. $7 Match of the 7th set of parentheses in the last match (auto-local).
  7196. $8 Match of the 8th set of parentheses in the last match (auto-local).
  7197. $9 Match of the 9th set of parentheses in the last match (auto-local).
  7198. $& The string matched by the last pattern match (auto-local).
  7199. $\\=' The string after what was matched by the last match (auto-local).
  7200. $\\=` The string before what was matched by the last match (auto-local).
  7201. $( The real gid of this process.
  7202. $) The effective gid of this process.
  7203. $* Deprecated: Set to 1 to do multiline matching within a string.
  7204. $+ The last bracket matched by the last search pattern.
  7205. $, The output field separator for the print operator.
  7206. $- The number of lines left on the page.
  7207. $. The current input line number of the last filehandle that was read.
  7208. $/ The input record separator, newline by default.
  7209. $0 Name of the file containing the current perl script (read/write).
  7210. $: String may be broken after these characters to fill ^-lines in a format.
  7211. $; Subscript separator for multi-dim array emulation. Default \"\\034\".
  7212. $< The real uid of this process.
  7213. $= The page length of the current output channel. Default is 60 lines.
  7214. $> The effective uid of this process.
  7215. $? The status returned by the last \\=`\\=`, pipe close or `system'.
  7216. $@ The perl error message from the last eval or do @var{EXPR} command.
  7217. $ARGV The name of the current file used with <> .
  7218. $[ Deprecated: The index of the first element/char in an array/string.
  7219. $\\ The output record separator for the print operator.
  7220. $] The perl version string as displayed with perl -v.
  7221. $^ The name of the current top-of-page format.
  7222. $^A The current value of the write() accumulator for format() lines.
  7223. $^D The value of the perl debug (-D) flags.
  7224. $^E Information about the last system error other than that provided by $!.
  7225. $^F The highest system file descriptor, ordinarily 2.
  7226. $^H The current set of syntax checks enabled by `use strict'.
  7227. $^I The value of the in-place edit extension (perl -i option).
  7228. $^L What formats output to perform a formfeed. Default is \\f.
  7229. $^M A buffer for emergency memory allocation when running out of memory.
  7230. $^O The operating system name under which this copy of Perl was built.
  7231. $^P Internal debugging flag.
  7232. $^T The time the script was started. Used by -A/-M/-C file tests.
  7233. $^W True if warnings are requested (perl -w flag).
  7234. $^X The name under which perl was invoked (argv[0] in C-speech).
  7235. $_ The default input and pattern-searching space.
  7236. $| Auto-flush after write/print on current output channel? Default 0.
  7237. $~ The name of the current report format.
  7238. ... % ... Modulo division.
  7239. ... %= ... Modulo division assignment.
  7240. %ENV Contains the current environment.
  7241. %INC List of files that have been require-d or do-ne.
  7242. %SIG Used to set signal handlers for various signals.
  7243. ... & ... Bitwise and.
  7244. ... && ... Logical and.
  7245. ... &&= ... Logical and assignment.
  7246. ... &= ... Bitwise and assignment.
  7247. ... * ... Multiplication.
  7248. ... ** ... Exponentiation.
  7249. *NAME Glob: all objects referred by NAME. *NAM1 = *NAM2 aliases NAM1 to NAM2.
  7250. &NAME(arg0, ...) Subroutine call. Arguments go to @_.
  7251. ... + ... Addition. +EXPR Makes EXPR into scalar context.
  7252. ++ Auto-increment (magical on strings). ++EXPR EXPR++
  7253. ... += ... Addition assignment.
  7254. , Comma operator.
  7255. ... - ... Subtraction.
  7256. -- Auto-decrement (NOT magical on strings). --EXPR EXPR--
  7257. ... -= ... Subtraction assignment.
  7258. -A Access time in days since script started.
  7259. -B File is a non-text (binary) file.
  7260. -C Inode change time in days since script started.
  7261. -M Age in days since script started.
  7262. -O File is owned by real uid.
  7263. -R File is readable by real uid.
  7264. -S File is a socket .
  7265. -T File is a text file.
  7266. -W File is writable by real uid.
  7267. -X File is executable by real uid.
  7268. -b File is a block special file.
  7269. -c File is a character special file.
  7270. -d File is a directory.
  7271. -e File exists .
  7272. -f File is a plain file.
  7273. -g File has setgid bit set.
  7274. -k File has sticky bit set.
  7275. -l File is a symbolic link.
  7276. -o File is owned by effective uid.
  7277. -p File is a named pipe (FIFO).
  7278. -r File is readable by effective uid.
  7279. -s File has non-zero size.
  7280. -t Tests if filehandle (STDIN by default) is opened to a tty.
  7281. -u File has setuid bit set.
  7282. -w File is writable by effective uid.
  7283. -x File is executable by effective uid.
  7284. -z File has zero size.
  7285. . Concatenate strings.
  7286. .. Range (list context); flip/flop (scalar context) operator.
  7287. .= Concatenate assignment strings
  7288. ... / ... Division. /PATTERN/ioxsmg Pattern match
  7289. ... /= ... Division assignment.
  7290. /PATTERN/ioxsmg Pattern match.
  7291. ... < ... Numeric less than. <pattern> Glob. See <NAME>, <> as well.
  7292. <NAME> Reads line from filehandle NAME (a bareword or dollar-bareword).
  7293. <pattern> Glob (Unless pattern is bareword/dollar-bareword - see <NAME>).
  7294. <> Reads line from union of files in @ARGV (= command line) and STDIN.
  7295. ... << ... Bitwise shift left. << start of HERE-DOCUMENT.
  7296. ... <= ... Numeric less than or equal to.
  7297. ... <=> ... Numeric compare.
  7298. ... = ... Assignment.
  7299. ... == ... Numeric equality.
  7300. ... =~ ... Search pattern, substitution, or translation
  7301. ... > ... Numeric greater than.
  7302. ... >= ... Numeric greater than or equal to.
  7303. ... >> ... Bitwise shift right.
  7304. ... >>= ... Bitwise shift right assignment.
  7305. ... ? ... : ... Condition=if-then-else operator. ?PAT? One-time pattern match.
  7306. ?PATTERN? One-time pattern match.
  7307. @ARGV Command line arguments (not including the command name - see $0).
  7308. @INC List of places to look for perl scripts during do/include/use.
  7309. @_ Parameter array for subroutines; result of split() unless in list context.
  7310. \\ Creates reference to what follows, like \\$var, or quotes non-\\w in strings.
  7311. \\0 Octal char, e.g. \\033.
  7312. \\E Case modification terminator. See \\Q, \\L, and \\U.
  7313. \\L Lowercase until \\E . See also \\l, lc.
  7314. \\U Upcase until \\E . See also \\u, uc.
  7315. \\Q Quote metacharacters until \\E . See also quotemeta.
  7316. \\a Alarm character (octal 007).
  7317. \\b Backspace character (octal 010).
  7318. \\c Control character, e.g. \\c[ .
  7319. \\e Escape character (octal 033).
  7320. \\f Formfeed character (octal 014).
  7321. \\l Lowercase the next character. See also \\L and \\u, lcfirst.
  7322. \\n Newline character (octal 012 on most systems).
  7323. \\r Return character (octal 015 on most systems).
  7324. \\t Tab character (octal 011).
  7325. \\u Upcase the next character. See also \\U and \\l, ucfirst.
  7326. \\x Hex character, e.g. \\x1b.
  7327. ... ^ ... Bitwise exclusive or.
  7328. __END__ Ends program source.
  7329. __DATA__ Ends program source.
  7330. __FILE__ Current (source) filename.
  7331. __LINE__ Current line in current source.
  7332. __PACKAGE__ Current package.
  7333. ARGV Default multi-file input filehandle. <ARGV> is a synonym for <>.
  7334. ARGVOUT Output filehandle with -i flag.
  7335. BEGIN { ... } Immediately executed (during compilation) piece of code.
  7336. END { ... } Pseudo-subroutine executed after the script finishes.
  7337. CHECK { ... } Pseudo-subroutine executed after the script is compiled.
  7338. INIT { ... } Pseudo-subroutine executed before the script starts running.
  7339. DATA Input filehandle for what follows after __END__ or __DATA__.
  7340. accept(NEWSOCKET,GENERICSOCKET)
  7341. alarm(SECONDS)
  7342. atan2(X,Y)
  7343. bind(SOCKET,NAME)
  7344. binmode(FILEHANDLE)
  7345. caller[(LEVEL)]
  7346. chdir(EXPR)
  7347. chmod(LIST)
  7348. chop[(LIST|VAR)]
  7349. chown(LIST)
  7350. chroot(FILENAME)
  7351. close(FILEHANDLE)
  7352. closedir(DIRHANDLE)
  7353. ... cmp ... String compare.
  7354. connect(SOCKET,NAME)
  7355. continue of { block } continue { block }. Is executed after `next' or at end.
  7356. cos(EXPR)
  7357. crypt(PLAINTEXT,SALT)
  7358. dbmclose(%HASH)
  7359. dbmopen(%HASH,DBNAME,MODE)
  7360. defined(EXPR)
  7361. delete($HASH{KEY})
  7362. die(LIST)
  7363. do { ... }|SUBR while|until EXPR executes at least once
  7364. do(EXPR|SUBR([LIST])) (with while|until executes at least once)
  7365. dump LABEL
  7366. each(%HASH)
  7367. endgrent
  7368. endhostent
  7369. endnetent
  7370. endprotoent
  7371. endpwent
  7372. endservent
  7373. eof[([FILEHANDLE])]
  7374. ... eq ... String equality.
  7375. eval(EXPR) or eval { BLOCK }
  7376. exec([TRUENAME] ARGV0, ARGVs) or exec(SHELL_COMMAND_LINE)
  7377. exit(EXPR)
  7378. exp(EXPR)
  7379. fcntl(FILEHANDLE,FUNCTION,SCALAR)
  7380. fileno(FILEHANDLE)
  7381. flock(FILEHANDLE,OPERATION)
  7382. for (EXPR;EXPR;EXPR) { ... }
  7383. foreach [VAR] (@ARRAY) { ... }
  7384. fork
  7385. ... ge ... String greater than or equal.
  7386. getc[(FILEHANDLE)]
  7387. getgrent
  7388. getgrgid(GID)
  7389. getgrnam(NAME)
  7390. gethostbyaddr(ADDR,ADDRTYPE)
  7391. gethostbyname(NAME)
  7392. gethostent
  7393. getlogin
  7394. getnetbyaddr(ADDR,ADDRTYPE)
  7395. getnetbyname(NAME)
  7396. getnetent
  7397. getpeername(SOCKET)
  7398. getpgrp(PID)
  7399. getppid
  7400. getpriority(WHICH,WHO)
  7401. getprotobyname(NAME)
  7402. getprotobynumber(NUMBER)
  7403. getprotoent
  7404. getpwent
  7405. getpwnam(NAME)
  7406. getpwuid(UID)
  7407. getservbyname(NAME,PROTO)
  7408. getservbyport(PORT,PROTO)
  7409. getservent
  7410. getsockname(SOCKET)
  7411. getsockopt(SOCKET,LEVEL,OPTNAME)
  7412. gmtime(EXPR)
  7413. goto LABEL
  7414. ... gt ... String greater than.
  7415. hex(EXPR)
  7416. if (EXPR) { ... } [ elsif (EXPR) { ... } ... ] [ else { ... } ] or EXPR if EXPR
  7417. index(STR,SUBSTR[,OFFSET])
  7418. int(EXPR)
  7419. ioctl(FILEHANDLE,FUNCTION,SCALAR)
  7420. join(EXPR,LIST)
  7421. keys(%HASH)
  7422. kill(LIST)
  7423. last [LABEL]
  7424. ... le ... String less than or equal.
  7425. length(EXPR)
  7426. link(OLDFILE,NEWFILE)
  7427. listen(SOCKET,QUEUESIZE)
  7428. local(LIST)
  7429. localtime(EXPR)
  7430. log(EXPR)
  7431. lstat(EXPR|FILEHANDLE|VAR)
  7432. ... lt ... String less than.
  7433. m/PATTERN/iogsmx
  7434. mkdir(FILENAME,MODE)
  7435. msgctl(ID,CMD,ARG)
  7436. msgget(KEY,FLAGS)
  7437. msgrcv(ID,VAR,SIZE,TYPE.FLAGS)
  7438. msgsnd(ID,MSG,FLAGS)
  7439. my VAR or my (VAR1,...) Introduces a lexical variable ($VAR, @ARR, or %HASH).
  7440. our VAR or our (VAR1,...) Lexically enable a global variable ($V, @A, or %H).
  7441. ... ne ... String inequality.
  7442. next [LABEL]
  7443. oct(EXPR)
  7444. open(FILEHANDLE[,EXPR])
  7445. opendir(DIRHANDLE,EXPR)
  7446. ord(EXPR) ASCII value of the first char of the string.
  7447. pack(TEMPLATE,LIST)
  7448. package NAME Introduces package context.
  7449. pipe(READHANDLE,WRITEHANDLE) Create a pair of filehandles on ends of a pipe.
  7450. pop(ARRAY)
  7451. print [FILEHANDLE] [(LIST)]
  7452. printf [FILEHANDLE] (FORMAT,LIST)
  7453. push(ARRAY,LIST)
  7454. q/STRING/ Synonym for \\='STRING\\='
  7455. qq/STRING/ Synonym for \"STRING\"
  7456. qx/STRING/ Synonym for \\=`STRING\\=`
  7457. rand[(EXPR)]
  7458. read(FILEHANDLE,SCALAR,LENGTH[,OFFSET])
  7459. readdir(DIRHANDLE)
  7460. readlink(EXPR)
  7461. recv(SOCKET,SCALAR,LEN,FLAGS)
  7462. redo [LABEL]
  7463. rename(OLDNAME,NEWNAME)
  7464. require [FILENAME | PERL_VERSION]
  7465. reset[(EXPR)]
  7466. return(LIST)
  7467. reverse(LIST)
  7468. rewinddir(DIRHANDLE)
  7469. rindex(STR,SUBSTR[,OFFSET])
  7470. rmdir(FILENAME)
  7471. s/PATTERN/REPLACEMENT/gieoxsm
  7472. scalar(EXPR)
  7473. seek(FILEHANDLE,POSITION,WHENCE)
  7474. seekdir(DIRHANDLE,POS)
  7475. select(FILEHANDLE | RBITS,WBITS,EBITS,TIMEOUT)
  7476. semctl(ID,SEMNUM,CMD,ARG)
  7477. semget(KEY,NSEMS,SIZE,FLAGS)
  7478. semop(KEY,...)
  7479. send(SOCKET,MSG,FLAGS[,TO])
  7480. setgrent
  7481. sethostent(STAYOPEN)
  7482. setnetent(STAYOPEN)
  7483. setpgrp(PID,PGRP)
  7484. setpriority(WHICH,WHO,PRIORITY)
  7485. setprotoent(STAYOPEN)
  7486. setpwent
  7487. setservent(STAYOPEN)
  7488. setsockopt(SOCKET,LEVEL,OPTNAME,OPTVAL)
  7489. shift[(ARRAY)]
  7490. shmctl(ID,CMD,ARG)
  7491. shmget(KEY,SIZE,FLAGS)
  7492. shmread(ID,VAR,POS,SIZE)
  7493. shmwrite(ID,STRING,POS,SIZE)
  7494. shutdown(SOCKET,HOW)
  7495. sin(EXPR)
  7496. sleep[(EXPR)]
  7497. socket(SOCKET,DOMAIN,TYPE,PROTOCOL)
  7498. socketpair(SOCKET1,SOCKET2,DOMAIN,TYPE,PROTOCOL)
  7499. sort [SUBROUTINE] (LIST)
  7500. splice(ARRAY,OFFSET[,LENGTH[,LIST]])
  7501. split[(/PATTERN/[,EXPR[,LIMIT]])]
  7502. sprintf(FORMAT,LIST)
  7503. sqrt(EXPR)
  7504. srand(EXPR)
  7505. stat(EXPR|FILEHANDLE|VAR)
  7506. study[(SCALAR)]
  7507. sub [NAME [(format)]] { BODY } sub NAME [(format)]; sub [(format)] {...}
  7508. substr(EXPR,OFFSET[,LEN])
  7509. symlink(OLDFILE,NEWFILE)
  7510. syscall(LIST)
  7511. sysread(FILEHANDLE,SCALAR,LENGTH[,OFFSET])
  7512. system([TRUENAME] ARGV0 [,ARGV]) or system(SHELL_COMMAND_LINE)
  7513. syswrite(FILEHANDLE,SCALAR,LENGTH[,OFFSET])
  7514. tell[(FILEHANDLE)]
  7515. telldir(DIRHANDLE)
  7516. time
  7517. times
  7518. tr/SEARCHLIST/REPLACEMENTLIST/cds
  7519. truncate(FILE|EXPR,LENGTH)
  7520. umask[(EXPR)]
  7521. undef[(EXPR)]
  7522. unless (EXPR) { ... } [ else { ... } ] or EXPR unless EXPR
  7523. unlink(LIST)
  7524. unpack(TEMPLATE,EXPR)
  7525. unshift(ARRAY,LIST)
  7526. until (EXPR) { ... } EXPR until EXPR
  7527. utime(LIST)
  7528. values(%HASH)
  7529. vec(EXPR,OFFSET,BITS)
  7530. wait
  7531. waitpid(PID,FLAGS)
  7532. wantarray Returns true if the sub/eval is called in list context.
  7533. warn(LIST)
  7534. while (EXPR) { ... } EXPR while EXPR
  7535. write[(EXPR|FILEHANDLE)]
  7536. ... x ... Repeat string or array.
  7537. x= ... Repetition assignment.
  7538. y/SEARCHLIST/REPLACEMENTLIST/
  7539. ... | ... Bitwise or.
  7540. ... || ... Logical or.
  7541. ~ ... Unary bitwise complement.
  7542. #! OS interpreter indicator. If contains `perl', used for options, and -x.
  7543. AUTOLOAD {...} Shorthand for `sub AUTOLOAD {...}'.
  7544. CORE:: Prefix to access builtin function if imported sub obscures it.
  7545. SUPER:: Prefix to lookup for a method in @ISA classes.
  7546. DESTROY Shorthand for `sub DESTROY {...}'.
  7547. ... EQ ... Obsolete synonym of `eq'.
  7548. ... GE ... Obsolete synonym of `ge'.
  7549. ... GT ... Obsolete synonym of `gt'.
  7550. ... LE ... Obsolete synonym of `le'.
  7551. ... LT ... Obsolete synonym of `lt'.
  7552. ... NE ... Obsolete synonym of `ne'.
  7553. abs [ EXPR ] absolute value
  7554. ... and ... Low-precedence synonym for &&.
  7555. bless REFERENCE [, PACKAGE] Makes reference into an object of a package.
  7556. chomp [LIST] Strips $/ off LIST/$_. Returns count. Special if $/ eq \\='\\='!
  7557. chr Converts a number to char with the same ordinal.
  7558. else Part of if/unless {BLOCK} elsif {BLOCK} else {BLOCK}.
  7559. elsif Part of if/unless {BLOCK} elsif {BLOCK} else {BLOCK}.
  7560. exists $HASH{KEY} True if the key exists.
  7561. format [NAME] = Start of output format. Ended by a single dot (.) on a line.
  7562. formline PICTURE, LIST Backdoor into \"format\" processing.
  7563. glob EXPR Synonym of <EXPR>.
  7564. lc [ EXPR ] Returns lowercased EXPR.
  7565. lcfirst [ EXPR ] Returns EXPR with lower-cased first letter.
  7566. grep EXPR,LIST or grep {BLOCK} LIST Filters LIST via EXPR/BLOCK.
  7567. map EXPR, LIST or map {BLOCK} LIST Applies EXPR/BLOCK to elts of LIST.
  7568. no PACKAGE [SYMBOL1, ...] Partial reverse for `use'. Runs `unimport' method.
  7569. not ... Low-precedence synonym for ! - negation.
  7570. ... or ... Low-precedence synonym for ||.
  7571. pos STRING Set/Get end-position of the last match over this string, see \\G.
  7572. quotemeta [ EXPR ] Quote regexp metacharacters.
  7573. qw/WORD1 .../ Synonym of split(\\='\\=', \\='WORD1 ...\\=')
  7574. readline FH Synonym of <FH>.
  7575. readpipe CMD Synonym of \\=`CMD\\=`.
  7576. ref [ EXPR ] Type of EXPR when dereferenced.
  7577. sysopen FH, FILENAME, MODE [, PERM] (MODE is numeric, see Fcntl.)
  7578. tie VAR, PACKAGE, LIST Hide an object behind a simple Perl variable.
  7579. tied Returns internal object for a tied data.
  7580. uc [ EXPR ] Returns upcased EXPR.
  7581. ucfirst [ EXPR ] Returns EXPR with upcased first letter.
  7582. untie VAR Unlink an object from a simple Perl variable.
  7583. use PACKAGE [SYMBOL1, ...] Compile-time `require' with consequent `import'.
  7584. ... xor ... Low-precedence synonym for exclusive or.
  7585. prototype \\&SUB Returns prototype of the function given a reference.
  7586. =head1 Top-level heading.
  7587. =head2 Second-level heading.
  7588. =head3 Third-level heading (is there such?).
  7589. =over [ NUMBER ] Start list.
  7590. =item [ TITLE ] Start new item in the list.
  7591. =back End list.
  7592. =cut Switch from POD to Perl.
  7593. =pod Switch from Perl to POD.
  7594. ")
  7595. (defun cperl-switch-to-doc-buffer (&optional interactive)
  7596. "Go to the perl documentation buffer and insert the documentation."
  7597. (interactive "p")
  7598. (let ((buf (get-buffer-create cperl-doc-buffer)))
  7599. (if interactive
  7600. (switch-to-buffer-other-window buf)
  7601. (set-buffer buf))
  7602. (if (= (buffer-size) 0)
  7603. (progn
  7604. (insert (documentation-property 'cperl-short-docs
  7605. 'variable-documentation))
  7606. (setq buffer-read-only t)))))
  7607. (defun cperl-beautify-regexp-piece (b e embed level)
  7608. ;; b is before the starting delimiter, e before the ending
  7609. ;; e should be a marker, may be changed, but remains "correct".
  7610. ;; EMBED is nil if we process the whole REx.
  7611. ;; The REx is guaranteed to have //x
  7612. ;; LEVEL shows how many levels deep to go
  7613. ;; position at enter and at leave is not defined
  7614. (let (s c tmp (m (make-marker)) (m1 (make-marker)) c1 spaces inline code pos)
  7615. (if embed
  7616. (progn
  7617. (goto-char b)
  7618. (setq c (if (eq embed t) (current-indentation) (current-column)))
  7619. (cond ((looking-at "(\\?\\\\#") ; (?#) wrongly commented when //x-ing
  7620. (forward-char 2)
  7621. (delete-char 1)
  7622. (forward-char 1))
  7623. ((looking-at "(\\?[^a-zA-Z]")
  7624. (forward-char 3))
  7625. ((looking-at "(\\?") ; (?i)
  7626. (forward-char 2))
  7627. (t
  7628. (forward-char 1))))
  7629. (goto-char (1+ b))
  7630. (setq c (1- (current-column))))
  7631. (setq c1 (+ c (or cperl-regexp-indent-step cperl-indent-level)))
  7632. (or (looking-at "[ \t]*[\n#]")
  7633. (progn
  7634. (insert "\n")))
  7635. (goto-char e)
  7636. (beginning-of-line)
  7637. (if (re-search-forward "[^ \t]" e t)
  7638. (progn ; Something before the ending delimiter
  7639. (goto-char e)
  7640. (delete-horizontal-space)
  7641. (insert "\n")
  7642. (cperl-make-indent c)
  7643. (set-marker e (point))))
  7644. (goto-char b)
  7645. (end-of-line 2)
  7646. (while (< (point) (marker-position e))
  7647. (beginning-of-line)
  7648. (setq s (point)
  7649. inline t)
  7650. (skip-chars-forward " \t")
  7651. (delete-region s (point))
  7652. (cperl-make-indent c1)
  7653. (while (and
  7654. inline
  7655. (looking-at
  7656. (concat "\\([a-zA-Z0-9]+[^*+{?]\\)" ; 1 word
  7657. "\\|" ; Embedded variable
  7658. "\\$\\([a-zA-Z0-9_]+\\([[{]\\)?\\|[^\n \t)|]\\)" ; 2 3
  7659. "\\|" ; $ ^
  7660. "[$^]"
  7661. "\\|" ; simple-code simple-code*?
  7662. "\\(\\\\.\\|[^][()#|*+?\n]\\)\\([*+{?]\\??\\)?" ; 4 5
  7663. "\\|" ; Class
  7664. "\\(\\[\\)" ; 6
  7665. "\\|" ; Grouping
  7666. "\\((\\(\\?\\)?\\)" ; 7 8
  7667. "\\|" ; |
  7668. "\\(|\\)"))) ; 9
  7669. (goto-char (match-end 0))
  7670. (setq spaces t)
  7671. (cond ((match-beginning 1) ; Alphanum word + junk
  7672. (forward-char -1))
  7673. ((or (match-beginning 3) ; $ab[12]
  7674. (and (match-beginning 5) ; X* X+ X{2,3}
  7675. (eq (preceding-char) ?\{)))
  7676. (forward-char -1)
  7677. (forward-sexp 1))
  7678. ((and ; [], already syntaxified
  7679. (match-beginning 6)
  7680. cperl-regexp-scan
  7681. cperl-use-syntax-table-text-property)
  7682. (forward-char -1)
  7683. (forward-sexp 1)
  7684. (or (eq (preceding-char) ?\])
  7685. (error "[]-group not terminated"))
  7686. (re-search-forward
  7687. "\\=\\([*+?]\\|{[0-9]+\\(,[0-9]*\\)?}\\)\\??" e t))
  7688. ((match-beginning 6) ; []
  7689. (setq tmp (point))
  7690. (if (looking-at "\\^?\\]")
  7691. (goto-char (match-end 0)))
  7692. ;; XXXX POSIX classes?!
  7693. (while (and (not pos)
  7694. (re-search-forward "\\[:\\|\\]" e t))
  7695. (if (eq (preceding-char) ?:)
  7696. (or (re-search-forward ":\\]" e t)
  7697. (error "[:POSIX:]-group in []-group not terminated"))
  7698. (setq pos t)))
  7699. (or (eq (preceding-char) ?\])
  7700. (error "[]-group not terminated"))
  7701. (re-search-forward
  7702. "\\=\\([*+?]\\|{[0-9]+\\(,[0-9]*\\)?}\\)\\??" e t))
  7703. ((match-beginning 7) ; ()
  7704. (goto-char (match-beginning 0))
  7705. (setq pos (current-column))
  7706. (or (eq pos c1)
  7707. (progn
  7708. (delete-horizontal-space)
  7709. (insert "\n")
  7710. (cperl-make-indent c1)))
  7711. (setq tmp (point))
  7712. (forward-sexp 1)
  7713. ;; (or (forward-sexp 1)
  7714. ;; (progn
  7715. ;; (goto-char tmp)
  7716. ;; (error "()-group not terminated")))
  7717. (set-marker m (1- (point)))
  7718. (set-marker m1 (point))
  7719. (if (= level 1)
  7720. (if (progn ; indent rigidly if multiline
  7721. ;; In fact does not make a lot of sense, since
  7722. ;; the starting position can be already lost due
  7723. ;; to insertion of "\n" and " "
  7724. (goto-char tmp)
  7725. (search-forward "\n" m1 t))
  7726. (indent-rigidly (point) m1 (- c1 pos)))
  7727. (setq level (1- level))
  7728. (cond
  7729. ((not (match-beginning 8))
  7730. (cperl-beautify-regexp-piece tmp m t level))
  7731. ((eq (char-after (+ 2 tmp)) ?\{) ; Code
  7732. t)
  7733. ((eq (char-after (+ 2 tmp)) ?\() ; Conditional
  7734. (goto-char (+ 2 tmp))
  7735. (forward-sexp 1)
  7736. (cperl-beautify-regexp-piece (point) m t level))
  7737. ((eq (char-after (+ 2 tmp)) ?<) ; Lookbehind
  7738. (goto-char (+ 3 tmp))
  7739. (cperl-beautify-regexp-piece (point) m t level))
  7740. (t
  7741. (cperl-beautify-regexp-piece tmp m t level))))
  7742. (goto-char m1)
  7743. (cond ((looking-at "[*+?]\\??")
  7744. (goto-char (match-end 0)))
  7745. ((eq (following-char) ?\{)
  7746. (forward-sexp 1)
  7747. (if (eq (following-char) ?\?)
  7748. (forward-char))))
  7749. (skip-chars-forward " \t")
  7750. (setq spaces nil)
  7751. (if (looking-at "[#\n]")
  7752. (progn
  7753. (or (eolp) (indent-for-comment))
  7754. (beginning-of-line 2))
  7755. (delete-horizontal-space)
  7756. (insert "\n"))
  7757. (end-of-line)
  7758. (setq inline nil))
  7759. ((match-beginning 9) ; |
  7760. (forward-char -1)
  7761. (setq tmp (point))
  7762. (beginning-of-line)
  7763. (if (re-search-forward "[^ \t]" tmp t)
  7764. (progn
  7765. (goto-char tmp)
  7766. (delete-horizontal-space)
  7767. (insert "\n"))
  7768. ;; first at line
  7769. (delete-region (point) tmp))
  7770. (cperl-make-indent c)
  7771. (forward-char 1)
  7772. (skip-chars-forward " \t")
  7773. (setq spaces nil)
  7774. (if (looking-at "[#\n]")
  7775. (beginning-of-line 2)
  7776. (delete-horizontal-space)
  7777. (insert "\n"))
  7778. (end-of-line)
  7779. (setq inline nil)))
  7780. (or (looking-at "[ \t\n]")
  7781. (not spaces)
  7782. (insert " "))
  7783. (skip-chars-forward " \t"))
  7784. (or (looking-at "[#\n]")
  7785. (error "Unknown code `%s' in a regexp"
  7786. (buffer-substring (point) (1+ (point)))))
  7787. (and inline (end-of-line 2)))
  7788. ;; Special-case the last line of group
  7789. (if (and (>= (point) (marker-position e))
  7790. (/= (current-indentation) c))
  7791. (progn
  7792. (beginning-of-line)
  7793. (cperl-make-indent c)))))
  7794. (defun cperl-make-regexp-x ()
  7795. ;; Returns position of the start
  7796. ;; XXX this is called too often! Need to cache the result!
  7797. (save-excursion
  7798. (or cperl-use-syntax-table-text-property
  7799. (error "I need to have a regexp marked!"))
  7800. ;; Find the start
  7801. (if (looking-at "\\s|")
  7802. nil ; good already
  7803. (if (or (looking-at "\\([smy]\\|qr\\)\\s|")
  7804. (and (eq (preceding-char) ?q)
  7805. (looking-at "\\(r\\)\\s|")))
  7806. (goto-char (match-end 1))
  7807. (re-search-backward "\\s|"))) ; Assume it is scanned already.
  7808. ;;(forward-char 1)
  7809. (let ((b (point)) (e (make-marker)) have-x delim (c (current-column))
  7810. (sub-p (eq (preceding-char) ?s)) s)
  7811. (forward-sexp 1)
  7812. (set-marker e (1- (point)))
  7813. (setq delim (preceding-char))
  7814. (if (and sub-p (eq delim (char-after (- (point) 2))))
  7815. (error "Possible s/blah// - do not know how to deal with"))
  7816. (if sub-p (forward-sexp 1))
  7817. (if (looking-at "\\sw*x")
  7818. (setq have-x t)
  7819. (insert "x"))
  7820. ;; Protect fragile " ", "#"
  7821. (if have-x nil
  7822. (goto-char (1+ b))
  7823. (while (re-search-forward "\\(\\=\\|[^\\\\]\\)\\(\\\\\\\\\\)*[ \t\n#]" e t) ; Need to include (?#) too?
  7824. (forward-char -1)
  7825. (insert "\\")
  7826. (forward-char 1)))
  7827. b)))
  7828. (defun cperl-beautify-regexp (&optional deep)
  7829. "Do it. (Experimental, may change semantics, recheck the result.)
  7830. We suppose that the regexp is scanned already."
  7831. (interactive "P")
  7832. (setq deep (if deep (prefix-numeric-value deep) -1))
  7833. (save-excursion
  7834. (goto-char (cperl-make-regexp-x))
  7835. (let ((b (point)) (e (make-marker)))
  7836. (forward-sexp 1)
  7837. (set-marker e (1- (point)))
  7838. (cperl-beautify-regexp-piece b e nil deep))))
  7839. (defun cperl-regext-to-level-start ()
  7840. "Goto start of an enclosing group in regexp.
  7841. We suppose that the regexp is scanned already."
  7842. (interactive)
  7843. (let ((limit (cperl-make-regexp-x)) done)
  7844. (while (not done)
  7845. (or (eq (following-char) ?\()
  7846. (search-backward "(" (1+ limit) t)
  7847. (error "Cannot find `(' which starts a group"))
  7848. (setq done
  7849. (save-excursion
  7850. (skip-chars-backward "\\")
  7851. (looking-at "\\(\\\\\\\\\\)*(")))
  7852. (or done (forward-char -1)))))
  7853. (defun cperl-contract-level ()
  7854. "Find an enclosing group in regexp and contract it.
  7855. \(Experimental, may change semantics, recheck the result.)
  7856. We suppose that the regexp is scanned already."
  7857. (interactive)
  7858. ;; (save-excursion ; Can't, breaks `cperl-contract-levels'
  7859. (cperl-regext-to-level-start)
  7860. (let ((b (point)) (e (make-marker)) c)
  7861. (forward-sexp 1)
  7862. (set-marker e (1- (point)))
  7863. (goto-char b)
  7864. (while (re-search-forward "\\(#\\)\\|\n" e 'to-end)
  7865. (cond
  7866. ((match-beginning 1) ; #-comment
  7867. (or c (setq c (current-indentation)))
  7868. (beginning-of-line 2) ; Skip
  7869. (cperl-make-indent c))
  7870. (t
  7871. (delete-char -1)
  7872. (just-one-space))))))
  7873. (defun cperl-contract-levels ()
  7874. "Find an enclosing group in regexp and contract all the kids.
  7875. \(Experimental, may change semantics, recheck the result.)
  7876. We suppose that the regexp is scanned already."
  7877. (interactive)
  7878. (save-excursion
  7879. (condition-case nil
  7880. (cperl-regext-to-level-start)
  7881. (error ; We are outside outermost group
  7882. (goto-char (cperl-make-regexp-x))))
  7883. (let ((b (point)) (e (make-marker)) s c)
  7884. (forward-sexp 1)
  7885. (set-marker e (1- (point)))
  7886. (goto-char (1+ b))
  7887. (while (re-search-forward "\\(\\\\\\\\\\)\\|(" e t)
  7888. (cond
  7889. ((match-beginning 1) ; Skip
  7890. nil)
  7891. (t ; Group
  7892. (cperl-contract-level)))))))
  7893. (defun cperl-beautify-level (&optional deep)
  7894. "Find an enclosing group in regexp and beautify it.
  7895. \(Experimental, may change semantics, recheck the result.)
  7896. We suppose that the regexp is scanned already."
  7897. (interactive "P")
  7898. (setq deep (if deep (prefix-numeric-value deep) -1))
  7899. (save-excursion
  7900. (cperl-regext-to-level-start)
  7901. (let ((b (point)) (e (make-marker)))
  7902. (forward-sexp 1)
  7903. (set-marker e (1- (point)))
  7904. (cperl-beautify-regexp-piece b e 'level deep))))
  7905. (defun cperl-invert-if-unless-modifiers ()
  7906. "Change `B if A;' into `if (A) {B}' etc if possible.
  7907. \(Unfinished.)"
  7908. (interactive)
  7909. (let (A B pre-B post-B pre-if post-if pre-A post-A if-string
  7910. (w-rex "\\<\\(if\\|unless\\|while\\|until\\|for\\|foreach\\)\\>"))
  7911. (and (= (char-syntax (preceding-char)) ?w)
  7912. (forward-sexp -1))
  7913. (setq pre-if (point))
  7914. (cperl-backward-to-start-of-expr)
  7915. (setq pre-B (point))
  7916. (forward-sexp 1) ; otherwise forward-to-end-of-expr is NOP
  7917. (cperl-forward-to-end-of-expr)
  7918. (setq post-A (point))
  7919. (goto-char pre-if)
  7920. (or (looking-at w-rex)
  7921. ;; Find the position
  7922. (progn (goto-char post-A)
  7923. (while (and
  7924. (not (looking-at w-rex))
  7925. (> (point) pre-B))
  7926. (forward-sexp -1))
  7927. (setq pre-if (point))))
  7928. (or (looking-at w-rex)
  7929. (error "Can't find `if', `unless', `while', `until', `for' or `foreach'"))
  7930. ;; 1 B 2 ... 3 B-com ... 4 if 5 ... if-com 6 ... 7 A 8
  7931. (setq if-string (buffer-substring (match-beginning 0) (match-end 0)))
  7932. ;; First, simple part: find code boundaries
  7933. (forward-sexp 1)
  7934. (setq post-if (point))
  7935. (forward-sexp -2)
  7936. (forward-sexp 1)
  7937. (setq post-B (point))
  7938. (cperl-backward-to-start-of-expr)
  7939. (setq pre-B (point))
  7940. (setq B (buffer-substring pre-B post-B))
  7941. (goto-char pre-if)
  7942. (forward-sexp 2)
  7943. (forward-sexp -1)
  7944. ;; May be after $, @, $# etc of a variable
  7945. (skip-chars-backward "$@%#")
  7946. (setq pre-A (point))
  7947. (cperl-forward-to-end-of-expr)
  7948. (setq post-A (point))
  7949. (setq A (buffer-substring pre-A post-A))
  7950. ;; Now modify (from end, to not break the stuff)
  7951. (skip-chars-forward " \t;")
  7952. (delete-region pre-A (point)) ; we move to pre-A
  7953. (insert "\n" B ";\n}")
  7954. (and (looking-at "[ \t]*#") (cperl-indent-for-comment))
  7955. (delete-region pre-if post-if)
  7956. (delete-region pre-B post-B)
  7957. (goto-char pre-B)
  7958. (insert if-string " (" A ") {")
  7959. (setq post-B (point))
  7960. (if (looking-at "[ \t]+$")
  7961. (delete-horizontal-space)
  7962. (if (looking-at "[ \t]*#")
  7963. (cperl-indent-for-comment)
  7964. (just-one-space)))
  7965. (forward-line 1)
  7966. (if (looking-at "[ \t]*$")
  7967. (progn ; delete line
  7968. (delete-horizontal-space)
  7969. (delete-region (point) (1+ (point)))))
  7970. (cperl-indent-line)
  7971. (goto-char (1- post-B))
  7972. (forward-sexp 1)
  7973. (cperl-indent-line)
  7974. (goto-char pre-B)))
  7975. (defun cperl-invert-if-unless ()
  7976. "Change `if (A) {B}' into `B if A;' etc (or visa versa) if possible.
  7977. If the cursor is not on the leading keyword of the BLOCK flavor of
  7978. construct, will assume it is the STATEMENT flavor, so will try to find
  7979. the appropriate statement modifier."
  7980. (interactive)
  7981. (and (= (char-syntax (preceding-char)) ?w)
  7982. (forward-sexp -1))
  7983. (if (looking-at "\\<\\(if\\|unless\\|while\\|until\\|for\\|foreach\\)\\>")
  7984. (let ((pre-if (point))
  7985. pre-A post-A pre-B post-B A B state p end-B-code is-block B-comment
  7986. (if-string (buffer-substring (match-beginning 0) (match-end 0))))
  7987. (forward-sexp 2)
  7988. (setq post-A (point))
  7989. (forward-sexp -1)
  7990. (setq pre-A (point))
  7991. (setq is-block (and (eq (following-char) ?\( )
  7992. (save-excursion
  7993. (condition-case nil
  7994. (progn
  7995. (forward-sexp 2)
  7996. (forward-sexp -1)
  7997. (eq (following-char) ?\{ ))
  7998. (error nil)))))
  7999. (if is-block
  8000. (progn
  8001. (goto-char post-A)
  8002. (forward-sexp 1)
  8003. (setq post-B (point))
  8004. (forward-sexp -1)
  8005. (setq pre-B (point))
  8006. (if (and (eq (following-char) ?\{ )
  8007. (progn
  8008. (cperl-backward-to-noncomment post-A)
  8009. (eq (preceding-char) ?\) )))
  8010. (if (condition-case nil
  8011. (progn
  8012. (goto-char post-B)
  8013. (forward-sexp 1)
  8014. (forward-sexp -1)
  8015. (looking-at "\\<els\\(e\\|if\\)\\>"))
  8016. (error nil))
  8017. (error
  8018. "`%s' (EXPR) {BLOCK} with `else'/`elsif'" if-string)
  8019. (goto-char (1- post-B))
  8020. (cperl-backward-to-noncomment pre-B)
  8021. (if (eq (preceding-char) ?\;)
  8022. (forward-char -1))
  8023. (setq end-B-code (point))
  8024. (goto-char pre-B)
  8025. (while (re-search-forward "\\<\\(for\\|foreach\\|if\\|unless\\|while\\|until\\)\\>\\|;" end-B-code t)
  8026. (setq p (match-beginning 0)
  8027. A (buffer-substring p (match-end 0))
  8028. state (parse-partial-sexp pre-B p))
  8029. (or (nth 3 state)
  8030. (nth 4 state)
  8031. (nth 5 state)
  8032. (error "`%s' inside `%s' BLOCK" A if-string))
  8033. (goto-char (match-end 0)))
  8034. ;; Finally got it
  8035. (goto-char (1+ pre-B))
  8036. (skip-chars-forward " \t\n")
  8037. (setq B (buffer-substring (point) end-B-code))
  8038. (goto-char end-B-code)
  8039. (or (looking-at ";?[ \t\n]*}")
  8040. (progn
  8041. (skip-chars-forward "; \t\n")
  8042. (setq B-comment
  8043. (buffer-substring (point) (1- post-B)))))
  8044. (and (equal B "")
  8045. (setq B "1"))
  8046. (goto-char (1- post-A))
  8047. (cperl-backward-to-noncomment pre-A)
  8048. (or (looking-at "[ \t\n]*)")
  8049. (goto-char (1- post-A)))
  8050. (setq p (point))
  8051. (goto-char (1+ pre-A))
  8052. (skip-chars-forward " \t\n")
  8053. (setq A (buffer-substring (point) p))
  8054. (delete-region pre-B post-B)
  8055. (delete-region pre-A post-A)
  8056. (goto-char pre-if)
  8057. (insert B " ")
  8058. (and B-comment (insert B-comment " "))
  8059. (just-one-space)
  8060. (forward-word 1)
  8061. (setq pre-A (point))
  8062. (insert " " A ";")
  8063. (delete-horizontal-space)
  8064. (setq post-B (point))
  8065. (if (looking-at "#")
  8066. (indent-for-comment))
  8067. (goto-char post-B)
  8068. (forward-char -1)
  8069. (delete-horizontal-space)
  8070. (goto-char pre-A)
  8071. (just-one-space)
  8072. (goto-char pre-if)
  8073. (setq pre-A (set-marker (make-marker) pre-A))
  8074. (while (<= (point) (marker-position pre-A))
  8075. (cperl-indent-line)
  8076. (forward-line 1))
  8077. (goto-char (marker-position pre-A))
  8078. (if B-comment
  8079. (progn
  8080. (forward-line -1)
  8081. (indent-for-comment)
  8082. (goto-char (marker-position pre-A)))))
  8083. (error "`%s' (EXPR) not with an {BLOCK}" if-string)))
  8084. ;; (error "`%s' not with an (EXPR)" if-string)
  8085. (forward-sexp -1)
  8086. (cperl-invert-if-unless-modifiers)))
  8087. ;;(error "Not at `if', `unless', `while', `until', `for' or `foreach'")
  8088. (cperl-invert-if-unless-modifiers)))
  8089. (declare-function Man-getpage-in-background "man" (topic))
  8090. ;;; By Anthony Foiani <afoiani@uswest.com>
  8091. ;;; Getting help on modules in C-h f ?
  8092. ;;; This is a modified version of `man'.
  8093. ;;; Need to teach it how to lookup functions
  8094. ;;;###autoload
  8095. (defun cperl-perldoc (word)
  8096. "Run `perldoc' on WORD."
  8097. (interactive
  8098. (list (let* ((default-entry (cperl-word-at-point))
  8099. (input (read-string
  8100. (format "perldoc entry%s: "
  8101. (if (string= default-entry "")
  8102. ""
  8103. (format " (default %s)" default-entry))))))
  8104. (if (string= input "")
  8105. (if (string= default-entry "")
  8106. (error "No perldoc args given")
  8107. default-entry)
  8108. input))))
  8109. (require 'man)
  8110. (let* ((case-fold-search nil)
  8111. (is-func (and
  8112. (string-match "^[a-z]+$" word)
  8113. (string-match (concat "^" word "\\>")
  8114. (documentation-property
  8115. 'cperl-short-docs
  8116. 'variable-documentation))))
  8117. (Man-switches "")
  8118. (manual-program (if is-func "perldoc -f" "perldoc")))
  8119. (cond
  8120. ((featurep 'xemacs)
  8121. (let ((Manual-program "perldoc")
  8122. (Manual-switches (if is-func (list "-f"))))
  8123. (manual-entry word)))
  8124. (t
  8125. (Man-getpage-in-background word)))))
  8126. ;;;###autoload
  8127. (defun cperl-perldoc-at-point ()
  8128. "Run a `perldoc' on the word around point."
  8129. (interactive)
  8130. (cperl-perldoc (cperl-word-at-point)))
  8131. (defcustom pod2man-program "pod2man"
  8132. "*File name for `pod2man'."
  8133. :type 'file
  8134. :group 'cperl)
  8135. ;;; By Nick Roberts <Nick.Roberts@src.bae.co.uk> (with changes)
  8136. (defun cperl-pod-to-manpage ()
  8137. "Create a virtual manpage in Emacs from the Perl Online Documentation."
  8138. (interactive)
  8139. (require 'man)
  8140. (let* ((pod2man-args (concat buffer-file-name " | nroff -man "))
  8141. (bufname (concat "Man " buffer-file-name))
  8142. (buffer (generate-new-buffer bufname)))
  8143. (with-current-buffer buffer
  8144. (let ((process-environment (copy-sequence process-environment)))
  8145. ;; Prevent any attempt to use display terminal fanciness.
  8146. (setenv "TERM" "dumb")
  8147. (set-process-sentinel
  8148. (start-process pod2man-program buffer "sh" "-c"
  8149. (format (cperl-pod2man-build-command) pod2man-args))
  8150. 'Man-bgproc-sentinel)))))
  8151. ;;; Updated version by him too
  8152. (defun cperl-build-manpage ()
  8153. "Create a virtual manpage in Emacs from the POD in the file."
  8154. (interactive)
  8155. (require 'man)
  8156. (cond
  8157. ((featurep 'xemacs)
  8158. (let ((Manual-program "perldoc"))
  8159. (manual-entry buffer-file-name)))
  8160. (t
  8161. (let* ((manual-program "perldoc")
  8162. (Man-switches ""))
  8163. (Man-getpage-in-background buffer-file-name)))))
  8164. (defun cperl-pod2man-build-command ()
  8165. "Builds the entire background manpage and cleaning command."
  8166. (let ((command (concat pod2man-program " %s 2>/dev/null"))
  8167. (flist (and (boundp 'Man-filter-list) Man-filter-list)))
  8168. (while (and flist (car flist))
  8169. (let ((pcom (car (car flist)))
  8170. (pargs (cdr (car flist))))
  8171. (setq command
  8172. (concat command " | " pcom " "
  8173. (mapconcat (lambda (phrase)
  8174. (if (not (stringp phrase))
  8175. (error "Malformed Man-filter-list"))
  8176. phrase)
  8177. pargs " ")))
  8178. (setq flist (cdr flist))))
  8179. command))
  8180. (defun cperl-next-interpolated-REx-1 ()
  8181. "Move point to next REx which has interpolated parts without //o.
  8182. Skips RExes consisting of one interpolated variable.
  8183. Note that skipped RExen are not performance hits."
  8184. (interactive "")
  8185. (cperl-next-interpolated-REx 1))
  8186. (defun cperl-next-interpolated-REx-0 ()
  8187. "Move point to next REx which has interpolated parts without //o."
  8188. (interactive "")
  8189. (cperl-next-interpolated-REx 0))
  8190. (defun cperl-next-interpolated-REx (&optional skip beg limit)
  8191. "Move point to next REx which has interpolated parts.
  8192. SKIP is a list of possible types to skip, BEG and LIMIT are the starting
  8193. point and the limit of search (default to point and end of buffer).
  8194. SKIP may be a number, then it behaves as list of numbers up to SKIP; this
  8195. semantic may be used as a numeric argument.
  8196. Types are 0 for / $rex /o (interpolated once), 1 for /$rex/ (if $rex is
  8197. a result of qr//, this is not a performance hit), t for the rest."
  8198. (interactive "P")
  8199. (if (numberp skip) (setq skip (list 0 skip)))
  8200. (or beg (setq beg (point)))
  8201. (or limit (setq limit (point-max))) ; needed for n-s-p-c
  8202. (let (pp)
  8203. (and (eq (get-text-property beg 'syntax-type) 'string)
  8204. (setq beg (next-single-property-change beg 'syntax-type nil limit)))
  8205. (cperl-map-pods-heres
  8206. (function (lambda (s e p)
  8207. (if (memq (get-text-property s 'REx-interpolated) skip)
  8208. t
  8209. (setq pp s)
  8210. nil))) ; nil stops
  8211. 'REx-interpolated beg limit)
  8212. (if pp (goto-char pp)
  8213. (message "No more interpolated REx"))))
  8214. ;;; Initial version contributed by Trey Belew
  8215. (defun cperl-here-doc-spell (&optional beg end)
  8216. "Spell-check HERE-documents in the Perl buffer.
  8217. If a region is highlighted, restricts to the region."
  8218. (interactive "")
  8219. (cperl-pod-spell t beg end))
  8220. (defun cperl-pod-spell (&optional do-heres beg end)
  8221. "Spell-check POD documentation.
  8222. If invoked with prefix argument, will do HERE-DOCs instead.
  8223. If a region is highlighted, restricts to the region."
  8224. (interactive "P")
  8225. (save-excursion
  8226. (let (beg end)
  8227. (if (cperl-mark-active)
  8228. (setq beg (min (mark) (point))
  8229. end (max (mark) (point)))
  8230. (setq beg (point-min)
  8231. end (point-max)))
  8232. (cperl-map-pods-heres (function
  8233. (lambda (s e p)
  8234. (if do-heres
  8235. (setq e (save-excursion
  8236. (goto-char e)
  8237. (forward-line -1)
  8238. (point))))
  8239. (ispell-region s e)
  8240. t))
  8241. (if do-heres 'here-doc-group 'in-pod)
  8242. beg end))))
  8243. (defun cperl-map-pods-heres (func &optional prop s end)
  8244. "Executes a function over regions of pods or here-documents.
  8245. PROP is the text-property to search for; default to `in-pod'. Stop when
  8246. function returns nil."
  8247. (let (pos posend has-prop (cont t))
  8248. (or prop (setq prop 'in-pod))
  8249. (or s (setq s (point-min)))
  8250. (or end (setq end (point-max)))
  8251. (cperl-update-syntaxification end end)
  8252. (save-excursion
  8253. (goto-char (setq pos s))
  8254. (while (and cont (< pos end))
  8255. (setq has-prop (get-text-property pos prop))
  8256. (setq posend (next-single-property-change pos prop nil end))
  8257. (and has-prop
  8258. (setq cont (funcall func pos posend prop)))
  8259. (setq pos posend)))))
  8260. ;;; Based on code by Masatake YAMATO:
  8261. (defun cperl-get-here-doc-region (&optional pos pod)
  8262. "Return HERE document region around the point.
  8263. Return nil if the point is not in a HERE document region. If POD is non-nil,
  8264. will return a POD section if point is in a POD section."
  8265. (or pos (setq pos (point)))
  8266. (cperl-update-syntaxification pos pos)
  8267. (if (or (eq 'here-doc (get-text-property pos 'syntax-type))
  8268. (and pod
  8269. (eq 'pod (get-text-property pos 'syntax-type))))
  8270. (let ((b (cperl-beginning-of-property pos 'syntax-type))
  8271. (e (next-single-property-change pos 'syntax-type)))
  8272. (cons b (or e (point-max))))))
  8273. (defun cperl-narrow-to-here-doc (&optional pos)
  8274. "Narrows editing region to the HERE-DOC at POS.
  8275. POS defaults to the point."
  8276. (interactive "d")
  8277. (or pos (setq pos (point)))
  8278. (let ((p (cperl-get-here-doc-region pos)))
  8279. (or p (error "Not inside a HERE document"))
  8280. (narrow-to-region (car p) (cdr p))
  8281. (message
  8282. "When you are finished with narrow editing, type C-x n w")))
  8283. (defun cperl-select-this-pod-or-here-doc (&optional pos)
  8284. "Select the HERE-DOC (or POD section) at POS.
  8285. POS defaults to the point."
  8286. (interactive "d")
  8287. (let ((p (cperl-get-here-doc-region pos t)))
  8288. (if p
  8289. (progn
  8290. (goto-char (car p))
  8291. (push-mark (cdr p) nil t)) ; Message, activate in transient-mode
  8292. (message "I do not think POS is in POD or a HERE-doc..."))))
  8293. (defun cperl-facemenu-add-face-function (face end)
  8294. "A callback to process user-initiated font-change requests.
  8295. Translates `bold', `italic', and `bold-italic' requests to insertion of
  8296. corresponding POD directives, and `underline' to C<> POD directive.
  8297. Such requests are usually bound to M-o LETTER."
  8298. (or (get-text-property (point) 'in-pod)
  8299. (error "Faces can only be set within POD"))
  8300. (setq facemenu-end-add-face (if (eq face 'bold-italic) ">>" ">"))
  8301. (cdr (or (assq face '((bold . "B<")
  8302. (italic . "I<")
  8303. (bold-italic . "B<I<")
  8304. (underline . "C<")))
  8305. (error "Face %s not configured for cperl-mode"
  8306. face))))
  8307. (defun cperl-time-fontification (&optional l step lim)
  8308. "Times how long it takes to do incremental fontification in a region.
  8309. L is the line to start at, STEP is the number of lines to skip when
  8310. doing next incremental fontification, LIM is the maximal number of
  8311. incremental fontification to perform. Messages are accumulated in
  8312. *Messages* buffer.
  8313. May be used for pinpointing which construct slows down buffer fontification:
  8314. start with default arguments, then refine the slowdown regions."
  8315. (interactive "nLine to start at: \nnStep to do incremental fontification: ")
  8316. (or l (setq l 1))
  8317. (or step (setq step 500))
  8318. (or lim (setq lim 40))
  8319. (let* ((timems (function (lambda ()
  8320. (let ((tt (current-time)))
  8321. (+ (* 1000 (nth 1 tt)) (/ (nth 2 tt) 1000))))))
  8322. (tt (funcall timems)) (c 0) delta tot)
  8323. (goto-char (point-min))
  8324. (forward-line (1- l))
  8325. (cperl-mode)
  8326. (setq tot (- (- tt (setq tt (funcall timems)))))
  8327. (message "cperl-mode at %s: %s" l tot)
  8328. (while (and (< c lim) (not (eobp)))
  8329. (forward-line step)
  8330. (setq l (+ l step))
  8331. (setq c (1+ c))
  8332. (cperl-update-syntaxification (point) (point))
  8333. (setq delta (- (- tt (setq tt (funcall timems)))) tot (+ tot delta))
  8334. (message "to %s:%6s,%7s" l delta tot))
  8335. tot))
  8336. (defvar font-lock-cache-position)
  8337. (defun cperl-emulate-lazy-lock (&optional window-size)
  8338. "Emulate `lazy-lock' without `condition-case', so `debug-on-error' works.
  8339. Start fontifying the buffer from the start (or end) using the given
  8340. WINDOW-SIZE (units is lines). Negative WINDOW-SIZE starts at end, and
  8341. goes backwards; default is -50. This function is not CPerl-specific; it
  8342. may be used to debug problems with delayed incremental fontification."
  8343. (interactive
  8344. "nSize of window for incremental fontification, negative goes backwards: ")
  8345. (or window-size (setq window-size -50))
  8346. (let ((pos (if (> window-size 0)
  8347. (point-min)
  8348. (point-max)))
  8349. p)
  8350. (goto-char pos)
  8351. (normal-mode)
  8352. ;; Why needed??? With older font-locks???
  8353. (set (make-local-variable 'font-lock-cache-position) (make-marker))
  8354. (while (if (> window-size 0)
  8355. (< pos (point-max))
  8356. (> pos (point-min)))
  8357. (setq p (progn
  8358. (forward-line window-size)
  8359. (point)))
  8360. (font-lock-fontify-region (min p pos) (max p pos))
  8361. (setq pos p))))
  8362. (defun cperl-lazy-install ()) ; Avoid a warning
  8363. (defun cperl-lazy-unstall ()) ; Avoid a warning
  8364. (if (fboundp 'run-with-idle-timer)
  8365. (progn
  8366. (defvar cperl-help-shown nil
  8367. "Non-nil means that the help was already shown now.")
  8368. (defvar cperl-lazy-installed nil
  8369. "Non-nil means that the lazy-help handlers are installed now.")
  8370. (defun cperl-lazy-install ()
  8371. "Switches on Auto-Help on Perl constructs (put in the message area).
  8372. Delay of auto-help controlled by `cperl-lazy-help-time'."
  8373. (interactive)
  8374. (make-local-variable 'cperl-help-shown)
  8375. (if (and (cperl-val 'cperl-lazy-help-time)
  8376. (not cperl-lazy-installed))
  8377. (progn
  8378. (add-hook 'post-command-hook 'cperl-lazy-hook)
  8379. (run-with-idle-timer
  8380. (cperl-val 'cperl-lazy-help-time 1000000 5)
  8381. t
  8382. 'cperl-get-help-defer)
  8383. (setq cperl-lazy-installed t))))
  8384. (defun cperl-lazy-unstall ()
  8385. "Switches off Auto-Help on Perl constructs (put in the message area).
  8386. Delay of auto-help controlled by `cperl-lazy-help-time'."
  8387. (interactive)
  8388. (remove-hook 'post-command-hook 'cperl-lazy-hook)
  8389. (cancel-function-timers 'cperl-get-help-defer)
  8390. (setq cperl-lazy-installed nil))
  8391. (defun cperl-lazy-hook ()
  8392. (setq cperl-help-shown nil))
  8393. (defun cperl-get-help-defer ()
  8394. (if (not (memq major-mode '(perl-mode cperl-mode))) nil
  8395. (let ((cperl-message-on-help-error nil) (cperl-help-from-timer t))
  8396. (cperl-get-help)
  8397. (setq cperl-help-shown t))))
  8398. (cperl-lazy-install)))
  8399. ;;; Plug for wrong font-lock:
  8400. (defun cperl-font-lock-unfontify-region-function (beg end)
  8401. (let* ((modified (buffer-modified-p)) (buffer-undo-list t)
  8402. (inhibit-read-only t) (inhibit-point-motion-hooks t)
  8403. (inhibit-modification-hooks t)
  8404. deactivate-mark buffer-file-name buffer-file-truename)
  8405. (remove-text-properties beg end '(face nil))
  8406. (if (and (not modified) (buffer-modified-p))
  8407. (set-buffer-modified-p nil))))
  8408. (defun cperl-font-lock-fontify-region-function (beg end loudly)
  8409. "Extends the region to safe positions, then calls the default function.
  8410. Newer `font-lock's can do it themselves.
  8411. We unwind only as far as needed for fontification. Syntaxification may
  8412. do extra unwind via `cperl-unwind-to-safe'."
  8413. (save-excursion
  8414. (goto-char beg)
  8415. (while (and beg
  8416. (progn
  8417. (beginning-of-line)
  8418. (eq (get-text-property (setq beg (point)) 'syntax-type)
  8419. 'multiline)))
  8420. (let ((new-beg (cperl-beginning-of-property beg 'syntax-type)))
  8421. (setq beg (if (= new-beg beg) nil new-beg))
  8422. (goto-char new-beg)))
  8423. (setq beg (point))
  8424. (goto-char end)
  8425. (while (and end
  8426. (progn
  8427. (or (bolp) (condition-case nil
  8428. (forward-line 1)
  8429. (error nil)))
  8430. (eq (get-text-property (setq end (point)) 'syntax-type)
  8431. 'multiline)))
  8432. (setq end (next-single-property-change end 'syntax-type nil (point-max)))
  8433. (goto-char end))
  8434. (setq end (point)))
  8435. (font-lock-default-fontify-region beg end loudly))
  8436. (defvar cperl-d-l nil)
  8437. (defun cperl-fontify-syntaxically (end)
  8438. ;; Some vars for debugging only
  8439. ;; (message "Syntaxifying...")
  8440. (let ((dbg (point)) (iend end) (idone cperl-syntax-done-to)
  8441. (istate (car cperl-syntax-state))
  8442. start from-start edebug-backtrace-buffer)
  8443. (if (eq cperl-syntaxify-by-font-lock 'backtrace)
  8444. (progn
  8445. (require 'edebug)
  8446. (let ((f 'edebug-backtrace))
  8447. (funcall f)))) ; Avoid compile-time warning
  8448. (or cperl-syntax-done-to
  8449. (setq cperl-syntax-done-to (point-min)
  8450. from-start t))
  8451. (setq start (if (and cperl-hook-after-change
  8452. (not from-start))
  8453. cperl-syntax-done-to ; Fontify without change; ignore start
  8454. ;; Need to forget what is after `start'
  8455. (min cperl-syntax-done-to (point))))
  8456. (goto-char start)
  8457. (beginning-of-line)
  8458. (setq start (point))
  8459. (and cperl-syntaxify-unwind
  8460. (setq end (cperl-unwind-to-safe t end)
  8461. start (point)))
  8462. (and (> end start)
  8463. (setq cperl-syntax-done-to start) ; In case what follows fails
  8464. (cperl-find-pods-heres start end t nil t))
  8465. (if (memq cperl-syntaxify-by-font-lock '(backtrace message))
  8466. (message "Syxify req=%s..%s actual=%s..%s done-to: %s=>%s statepos: %s=>%s"
  8467. dbg iend start end idone cperl-syntax-done-to
  8468. istate (car cperl-syntax-state))) ; For debugging
  8469. nil)) ; Do not iterate
  8470. (defun cperl-fontify-update (end)
  8471. (let ((pos (point-min)) prop posend)
  8472. (setq end (point-max))
  8473. (while (< pos end)
  8474. (setq prop (get-text-property pos 'cperl-postpone)
  8475. posend (next-single-property-change pos 'cperl-postpone nil end))
  8476. (and prop (put-text-property pos posend (car prop) (cdr prop)))
  8477. (setq pos posend)))
  8478. nil) ; Do not iterate
  8479. (defun cperl-fontify-update-bad (end)
  8480. ;; Since fontification happens with different region than syntaxification,
  8481. ;; do to the end of buffer, not to END;;; likewise, start earlier if needed
  8482. (let* ((pos (point)) (prop (get-text-property pos 'cperl-postpone)) posend)
  8483. (if prop
  8484. (setq pos (or (cperl-beginning-of-property
  8485. (cperl-1+ pos) 'cperl-postpone)
  8486. (point-min))))
  8487. (while (< pos end)
  8488. (setq posend (next-single-property-change pos 'cperl-postpone))
  8489. (and prop (put-text-property pos posend (car prop) (cdr prop)))
  8490. (setq pos posend)
  8491. (setq prop (get-text-property pos 'cperl-postpone))))
  8492. nil) ; Do not iterate
  8493. ;; Called when any modification is made to buffer text.
  8494. (defun cperl-after-change-function (beg end old-len)
  8495. ;; We should have been informed about changes by `font-lock'. Since it
  8496. ;; does not inform as which calls are deferred, do it ourselves
  8497. (if cperl-syntax-done-to
  8498. (setq cperl-syntax-done-to (min cperl-syntax-done-to beg))))
  8499. (defun cperl-update-syntaxification (from to)
  8500. (cond
  8501. ((not cperl-use-syntax-table-text-property) nil)
  8502. ((fboundp 'syntax-propertize) (syntax-propertize to))
  8503. ((and cperl-syntaxify-by-font-lock
  8504. (or (null cperl-syntax-done-to)
  8505. (< cperl-syntax-done-to to)))
  8506. (save-excursion
  8507. (goto-char from)
  8508. (cperl-fontify-syntaxically to)))))
  8509. (defvar cperl-version
  8510. (let ((v "Revision: 6.2"))
  8511. (string-match ":\\s *\\([0-9.]+\\)" v)
  8512. (substring v (match-beginning 1) (match-end 1)))
  8513. "Version of IZ-supported CPerl package this file is based on.")
  8514. (provide 'cperl-mode)
  8515. ;;; cperl-mode.el ends here