123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549 |
- This is /home/cyd/emacs/doc/lispref/../../info/elisp, produced by
- makeinfo version 4.13 from /home/cyd/emacs/doc/lispref/elisp.texi.
- This is the `GNU Emacs Lisp Reference Manual' corresponding to Emacs
- version 24.2.
- Copyright (C) 1990-1996, 1998-2012 Free Software Foundation, Inc.
- Permission is granted to copy, distribute and/or modify this
- document under the terms of the GNU Free Documentation License,
- Version 1.3 or any later version published by the Free Software
- Foundation; with the Invariant Sections being "GNU General Public
- License," with the Front-Cover texts being "A GNU Manual," and
- with the Back-Cover Texts as in (a) below. A copy of the license
- is included in the section entitled "GNU Free Documentation
- License."
- (a) The FSF's Back-Cover Text is: "You have the freedom to copy and
- modify this GNU manual. Buying copies from the FSF supports it in
- developing GNU and promoting software freedom."
- INFO-DIR-SECTION GNU Emacs Lisp
- START-INFO-DIR-ENTRY
- * Elisp: (elisp). The Emacs Lisp Reference Manual.
- END-INFO-DIR-ENTRY
- File: elisp, Node: Major Mode Conventions, Next: Auto Major Mode, Up: Major Modes
- 23.2.1 Major Mode Conventions
- -----------------------------
- The code for every major mode should follow various coding conventions,
- including conventions for local keymap and syntax table initialization,
- function and variable names, and hooks.
- If you use the `define-derived-mode' macro, it will take care of
- many of these conventions automatically. *Note Derived Modes::. Note
- also that Fundamental mode is an exception to many of these conventions,
- because it represents the default state of Emacs.
- The following list of conventions is only partial. Each major mode
- should aim for consistency in general with other Emacs major modes, as
- this makes Emacs as a whole more coherent. It is impossible to list
- here all the possible points where this issue might come up; if the
- Emacs developers point out an area where your major mode deviates from
- the usual conventions, please make it compatible.
- * Define a major mode command whose name ends in `-mode'. When
- called with no arguments, this command should switch to the new
- mode in the current buffer by setting up the keymap, syntax table,
- and buffer-local variables in an existing buffer. It should not
- change the buffer's contents.
- * Write a documentation string for this command that describes the
- special commands available in this mode. *Note Mode Help::.
- The documentation string may include the special documentation
- substrings, `\[COMMAND]', `\{KEYMAP}', and `\<KEYMAP>', which
- allow the help display to adapt automatically to the user's own
- key bindings. *Note Keys in Documentation::.
- * The major mode command should start by calling
- `kill-all-local-variables'. This runs the normal hook
- `change-major-mode-hook', then gets rid of the buffer-local
- variables of the major mode previously in effect. *Note Creating
- Buffer-Local::.
- * The major mode command should set the variable `major-mode' to the
- major mode command symbol. This is how `describe-mode' discovers
- which documentation to print.
- * The major mode command should set the variable `mode-name' to the
- "pretty" name of the mode, usually a string (but see *note Mode
- Line Data::, for other possible forms). The name of the mode
- appears in the mode line.
- * Since all global names are in the same name space, all the global
- variables, constants, and functions that are part of the mode
- should have names that start with the major mode name (or with an
- abbreviation of it if the name is long). *Note Coding
- Conventions::.
- * In a major mode for editing some kind of structured text, such as a
- programming language, indentation of text according to structure is
- probably useful. So the mode should set `indent-line-function' to
- a suitable function, and probably customize other variables for
- indentation. *Note Auto-Indentation::.
- * The major mode should usually have its own keymap, which is used
- as the local keymap in all buffers in that mode. The major mode
- command should call `use-local-map' to install this local map.
- *Note Active Keymaps::, for more information.
- This keymap should be stored permanently in a global variable named
- `MODENAME-mode-map'. Normally the library that defines the mode
- sets this variable.
- *Note Tips for Defining::, for advice about how to write the code
- to set up the mode's keymap variable.
- * The key sequences bound in a major mode keymap should usually
- start with `C-c', followed by a control character, a digit, or `{',
- `}', `<', `>', `:' or `;'. The other punctuation characters are
- reserved for minor modes, and ordinary letters are reserved for
- users.
- A major mode can also rebind the keys `M-n', `M-p' and `M-s'. The
- bindings for `M-n' and `M-p' should normally be some kind of
- "moving forward and backward", but this does not necessarily mean
- cursor motion.
- It is legitimate for a major mode to rebind a standard key
- sequence if it provides a command that does "the same job" in a
- way better suited to the text this mode is used for. For example,
- a major mode for editing a programming language might redefine
- `C-M-a' to "move to the beginning of a function" in a way that
- works better for that language.
- It is also legitimate for a major mode to rebind a standard key
- sequence whose standard meaning is rarely useful in that mode. For
- instance, minibuffer modes rebind `M-r', whose standard meaning is
- rarely of any use in the minibuffer. Major modes such as Dired or
- Rmail that do not allow self-insertion of text can reasonably
- redefine letters and other printing characters as special commands.
- * Major modes for editing text should not define <RET> to do
- anything other than insert a newline. However, it is ok for
- specialized modes for text that users don't directly edit, such as
- Dired and Info modes, to redefine <RET> to do something entirely
- different.
- * Major modes should not alter options that are primarily a matter
- of user preference, such as whether Auto-Fill mode is enabled.
- Leave this to each user to decide. However, a major mode should
- customize other variables so that Auto-Fill mode will work
- usefully _if_ the user decides to use it.
- * The mode may have its own syntax table or may share one with other
- related modes. If it has its own syntax table, it should store
- this in a variable named `MODENAME-mode-syntax-table'. *Note
- Syntax Tables::.
- * If the mode handles a language that has a syntax for comments, it
- should set the variables that define the comment syntax. *Note
- Options Controlling Comments: (emacs)Options for Comments.
- * The mode may have its own abbrev table or may share one with other
- related modes. If it has its own abbrev table, it should store
- this in a variable named `MODENAME-mode-abbrev-table'. If the
- major mode command defines any abbrevs itself, it should pass `t'
- for the SYSTEM-FLAG argument to `define-abbrev'. *Note Defining
- Abbrevs::.
- * The mode should specify how to do highlighting for Font Lock mode,
- by setting up a buffer-local value for the variable
- `font-lock-defaults' (*note Font Lock Mode::).
- * Each face that the mode defines should, if possible, inherit from
- an existing Emacs face. *Note Basic Faces::, and *note Faces for
- Font Lock::.
- * The mode should specify how Imenu should find the definitions or
- sections of a buffer, by setting up a buffer-local value for the
- variable `imenu-generic-expression', for the two variables
- `imenu-prev-index-position-function' and
- `imenu-extract-index-name-function', or for the variable
- `imenu-create-index-function' (*note Imenu::).
- * The mode can specify a local value for
- `eldoc-documentation-function' to tell ElDoc mode how to handle
- this mode.
- * The mode can specify how to complete various keywords by adding
- one or more buffer-local entries to the special hook
- `completion-at-point-functions'. *Note Completion in Buffers::.
- * To make a buffer-local binding for an Emacs customization
- variable, use `make-local-variable' in the major mode command, not
- `make-variable-buffer-local'. The latter function would make the
- variable local to every buffer in which it is subsequently set,
- which would affect buffers that do not use this mode. It is
- undesirable for a mode to have such global effects. *Note
- Buffer-Local Variables::.
- With rare exceptions, the only reasonable way to use
- `make-variable-buffer-local' in a Lisp package is for a variable
- which is used only within that package. Using it on a variable
- used by other packages would interfere with them.
- * Each major mode should have a normal "mode hook" named
- `MODENAME-mode-hook'. The very last thing the major mode command
- should do is to call `run-mode-hooks'. This runs the normal hook
- `change-major-mode-after-body-hook', the mode hook, and then the
- normal hook `after-change-major-mode-hook'. *Note Mode Hooks::.
- * The major mode command may start by calling some other major mode
- command (called the "parent mode") and then alter some of its
- settings. A mode that does this is called a "derived mode". The
- recommended way to define one is to use the `define-derived-mode'
- macro, but this is not required. Such a mode should call the
- parent mode command inside a `delay-mode-hooks' form. (Using
- `define-derived-mode' does this automatically.) *Note Derived
- Modes::, and *note Mode Hooks::.
- * If something special should be done if the user switches a buffer
- from this mode to any other major mode, this mode can set up a
- buffer-local value for `change-major-mode-hook' (*note Creating
- Buffer-Local::).
- * If this mode is appropriate only for specially-prepared text
- produced by the mode itself (rather than by the user typing at the
- keyboard or by an external file), then the major mode command
- symbol should have a property named `mode-class' with value
- `special', put on as follows:
- (put 'funny-mode 'mode-class 'special)
- This tells Emacs that new buffers created while the current buffer
- is in Funny mode should not be put in Funny mode, even though the
- default value of `major-mode' is `nil'. By default, the value of
- `nil' for `major-mode' means to use the current buffer's major
- mode when creating new buffers (*note Auto Major Mode::), but with
- such `special' modes, Fundamental mode is used instead. Modes
- such as Dired, Rmail, and Buffer List use this feature.
- The function `view-buffer' does not enable View mode in buffers
- whose mode-class is special, because such modes usually provide
- their own View-like bindings.
- The `define-derived-mode' macro automatically marks the derived
- mode as special if the parent mode is special. Special mode is a
- convenient parent for such modes to inherit from; *Note Basic
- Major Modes::.
- * If you want to make the new mode the default for files with certain
- recognizable names, add an element to `auto-mode-alist' to select
- the mode for those file names (*note Auto Major Mode::). If you
- define the mode command to autoload, you should add this element in
- the same file that calls `autoload'. If you use an autoload
- cookie for the mode command, you can also use an autoload cookie
- for the form that adds the element (*note autoload cookie::). If
- you do not autoload the mode command, it is sufficient to add the
- element in the file that contains the mode definition.
- * The top-level forms in the file defining the mode should be
- written so that they may be evaluated more than once without
- adverse consequences. For instance, use `defvar' or `defcustom'
- to set mode-related variables, so that they are not reinitialized
- if they already have a value (*note Defining Variables::).
- File: elisp, Node: Auto Major Mode, Next: Mode Help, Prev: Major Mode Conventions, Up: Major Modes
- 23.2.2 How Emacs Chooses a Major Mode
- -------------------------------------
- When Emacs visits a file, it automatically selects a major mode for the
- buffer based on information in the file name or in the file itself. It
- also processes local variables specified in the file text.
- -- Command: normal-mode &optional find-file
- This function establishes the proper major mode and buffer-local
- variable bindings for the current buffer. First it calls
- `set-auto-mode' (see below), then it runs `hack-local-variables'
- to parse, and bind or evaluate as appropriate, the file's local
- variables (*note File Local Variables::).
- If the FIND-FILE argument to `normal-mode' is non-`nil',
- `normal-mode' assumes that the `find-file' function is calling it.
- In this case, it may process local variables in the `-*-' line or
- at the end of the file. The variable `enable-local-variables'
- controls whether to do so. *Note Local Variables in Files:
- (emacs)File Variables, for the syntax of the local variables
- section of a file.
- If you run `normal-mode' interactively, the argument FIND-FILE is
- normally `nil'. In this case, `normal-mode' unconditionally
- processes any file local variables.
- The function calls `set-auto-mode' to choose a major mode. If this
- does not specify a mode, the buffer stays in the major mode
- determined by the default value of `major-mode' (see below).
- `normal-mode' uses `condition-case' around the call to the major
- mode command, so errors are caught and reported as a `File mode
- specification error', followed by the original error message.
- -- Function: set-auto-mode &optional keep-mode-if-same
- This function selects the major mode that is appropriate for the
- current buffer. It bases its decision (in order of precedence) on
- the `-*-' line, on any `mode:' local variable near the end of a
- file, on the `#!' line (using `interpreter-mode-alist'), on the
- text at the beginning of the buffer (using `magic-mode-alist'),
- and finally on the visited file name (using `auto-mode-alist').
- *Note How Major Modes are Chosen: (emacs)Choosing Modes. If
- `enable-local-variables' is `nil', `set-auto-mode' does not check
- the `-*-' line, or near the end of the file, for any mode tag.
- There are some file types where it is not appropriate to scan the
- file contents for a mode specifier. For example, a tar archive
- may happen to contain, near the end of the file, a member file
- that has a local variables section specifying a mode for that
- particular file. This should not be applied to the containing tar
- file. Similarly, a tiff image file might just happen to contain a
- first line that seems to match the `-*-' pattern. For these
- reasons, both these file extensions are members of the list
- INHIBIT-LOCAL-VARIABLES-REGEXPS. Add patterns to this list to
- prevent Emacs searching them for local variables of any kind (not
- just mode specifiers).
- If KEEP-MODE-IF-SAME is non-`nil', this function does not call the
- mode command if the buffer is already in the proper major mode.
- For instance, `set-visited-file-name' sets this to `t' to avoid
- killing buffer local variables that the user may have set.
- -- Function: set-buffer-major-mode buffer
- This function sets the major mode of BUFFER to the default value of
- `major-mode'; if that is `nil', it uses the current buffer's major
- mode (if that is suitable). As an exception, if BUFFER's name is
- `*scratch*', it sets the mode to `initial-major-mode'.
- The low-level primitives for creating buffers do not use this
- function, but medium-level commands such as `switch-to-buffer' and
- `find-file-noselect' use it whenever they create buffers.
- -- User Option: initial-major-mode
- The value of this variable determines the major mode of the initial
- `*scratch*' buffer. The value should be a symbol that is a major
- mode command. The default value is `lisp-interaction-mode'.
- -- Variable: interpreter-mode-alist
- This variable specifies major modes to use for scripts that
- specify a command interpreter in a `#!' line. Its value is an
- alist with elements of the form `(INTERPRETER . MODE)'; for
- example, `("perl" . perl-mode)' is one element present by default.
- The element says to use mode MODE if the file specifies an
- interpreter which matches INTERPRETER.
- -- Variable: magic-mode-alist
- This variable's value is an alist with elements of the form
- `(REGEXP . FUNCTION)', where REGEXP is a regular expression and
- FUNCTION is a function or `nil'. After visiting a file,
- `set-auto-mode' calls FUNCTION if the text at the beginning of the
- buffer matches REGEXP and FUNCTION is non-`nil'; if FUNCTION is
- `nil', `auto-mode-alist' gets to decide the mode.
- -- Variable: magic-fallback-mode-alist
- This works like `magic-mode-alist', except that it is handled only
- if `auto-mode-alist' does not specify a mode for this file.
- -- Variable: auto-mode-alist
- This variable contains an association list of file name patterns
- (regular expressions) and corresponding major mode commands.
- Usually, the file name patterns test for suffixes, such as `.el'
- and `.c', but this need not be the case. An ordinary element of
- the alist looks like `(REGEXP . MODE-FUNCTION)'.
- For example,
- (("\\`/tmp/fol/" . text-mode)
- ("\\.texinfo\\'" . texinfo-mode)
- ("\\.texi\\'" . texinfo-mode)
- ("\\.el\\'" . emacs-lisp-mode)
- ("\\.c\\'" . c-mode)
- ("\\.h\\'" . c-mode)
- ...)
- When you visit a file whose expanded file name (*note File Name
- Expansion::), with version numbers and backup suffixes removed
- using `file-name-sans-versions' (*note File Name Components::),
- matches a REGEXP, `set-auto-mode' calls the corresponding
- MODE-FUNCTION. This feature enables Emacs to select the proper
- major mode for most files.
- If an element of `auto-mode-alist' has the form `(REGEXP FUNCTION
- t)', then after calling FUNCTION, Emacs searches `auto-mode-alist'
- again for a match against the portion of the file name that did
- not match before. This feature is useful for uncompression
- packages: an entry of the form `("\\.gz\\'" FUNCTION t)' can
- uncompress the file and then put the uncompressed file in the
- proper mode according to the name sans `.gz'.
- Here is an example of how to prepend several pattern pairs to
- `auto-mode-alist'. (You might use this sort of expression in your
- init file.)
- (setq auto-mode-alist
- (append
- ;; File name (within directory) starts with a dot.
- '(("/\\.[^/]*\\'" . fundamental-mode)
- ;; File name has no dot.
- ("/[^\\./]*\\'" . fundamental-mode)
- ;; File name ends in `.C'.
- ("\\.C\\'" . c++-mode))
- auto-mode-alist))
- File: elisp, Node: Mode Help, Next: Derived Modes, Prev: Auto Major Mode, Up: Major Modes
- 23.2.3 Getting Help about a Major Mode
- --------------------------------------
- The `describe-mode' function provides information about major modes.
- It is normally bound to `C-h m'. It uses the value of the variable
- `major-mode' (*note Major Modes::), which is why every major mode
- command needs to set that variable.
- -- Command: describe-mode &optional buffer
- This command displays the documentation of the current buffer's
- major mode and minor modes. It uses the `documentation' function
- to retrieve the documentation strings of the major and minor mode
- commands (*note Accessing Documentation::).
- If called from Lisp with a non-nil BUFFER argument, this function
- displays the documentation for that buffer's major and minor
- modes, rather than those of the current buffer.
- File: elisp, Node: Derived Modes, Next: Basic Major Modes, Prev: Mode Help, Up: Major Modes
- 23.2.4 Defining Derived Modes
- -----------------------------
- The recommended way to define a new major mode is to derive it from an
- existing one using `define-derived-mode'. If there is no closely
- related mode, you should inherit from either `text-mode',
- `special-mode', or `prog-mode'. *Note Basic Major Modes::. If none of
- these are suitable, you can inherit from `fundamental-mode' (*note
- Major Modes::).
- -- Macro: define-derived-mode variant parent name docstring
- keyword-args... body...
- This macro defines VARIANT as a major mode command, using NAME as
- the string form of the mode name. VARIANT and PARENT should be
- unquoted symbols.
- The new command VARIANT is defined to call the function PARENT,
- then override certain aspects of that parent mode:
- * The new mode has its own sparse keymap, named `VARIANT-map'.
- `define-derived-mode' makes the parent mode's keymap the
- parent of the new map, unless `VARIANT-map' is already set
- and already has a parent.
- * The new mode has its own syntax table, kept in the variable
- `VARIANT-syntax-table', unless you override this using the
- `:syntax-table' keyword (see below). `define-derived-mode'
- makes the parent mode's syntax-table the parent of
- `VARIANT-syntax-table', unless the latter is already set and
- already has a parent different from the standard syntax table.
- * The new mode has its own abbrev table, kept in the variable
- `VARIANT-abbrev-table', unless you override this using the
- `:abbrev-table' keyword (see below).
- * The new mode has its own mode hook, `VARIANT-hook'. It runs
- this hook, after running the hooks of its ancestor modes, with
- `run-mode-hooks', as the last thing it does. *Note Mode
- Hooks::.
- In addition, you can specify how to override other aspects of
- PARENT with BODY. The command VARIANT evaluates the forms in BODY
- after setting up all its usual overrides, just before running the
- mode hooks.
- If PARENT has a non-`nil' `mode-class' symbol property, then
- `define-derived-mode' sets the `mode-class' property of VARIANT to
- the same value. This ensures, for example, that if PARENT is a
- special mode, then VARIANT is also a special mode (*note Major
- Mode Conventions::).
- You can also specify `nil' for PARENT. This gives the new mode no
- parent. Then `define-derived-mode' behaves as described above,
- but, of course, omits all actions connected with PARENT.
- The argument DOCSTRING specifies the documentation string for the
- new mode. `define-derived-mode' adds some general information
- about the mode's hook, followed by the mode's keymap, at the end
- of this documentation string. If you omit DOCSTRING,
- `define-derived-mode' generates a documentation string.
- The KEYWORD-ARGS are pairs of keywords and values. The values are
- evaluated. The following keywords are currently supported:
- `:syntax-table'
- You can use this to explicitly specify a syntax table for the
- new mode. If you specify a `nil' value, the new mode uses
- the same syntax table as PARENT, or the standard syntax table
- if PARENT is `nil'. (Note that this does _not_ follow the
- convention used for non-keyword arguments that a `nil' value
- is equivalent with not specifying the argument.)
- `:abbrev-table'
- You can use this to explicitly specify an abbrev table for
- the new mode. If you specify a `nil' value, the new mode
- uses the same abbrev table as PARENT, or
- `fundamental-mode-abbrev-table' if PARENT is `nil'. (Again,
- a `nil' value is _not_ equivalent to not specifying this
- keyword.)
- `:group'
- If this is specified, the value should be the customization
- group for this mode. (Not all major modes have one.) Only
- the (still experimental and unadvertised) command
- `customize-mode' currently uses this. `define-derived-mode'
- does _not_ automatically define the specified customization
- group.
- Here is a hypothetical example:
- (define-derived-mode hypertext-mode
- text-mode "Hypertext"
- "Major mode for hypertext.
- \\{hypertext-mode-map}"
- (setq case-fold-search nil))
- (define-key hypertext-mode-map
- [down-mouse-3] 'do-hyper-link)
- Do not write an `interactive' spec in the definition;
- `define-derived-mode' does that automatically.
- -- Function: derived-mode-p &rest modes
- This function returns non-`nil' if the current major mode is
- derived from any of the major modes given by the symbols MODES.
- File: elisp, Node: Basic Major Modes, Next: Mode Hooks, Prev: Derived Modes, Up: Major Modes
- 23.2.5 Basic Major Modes
- ------------------------
- Apart from Fundamental mode, there are three major modes that other
- major modes commonly derive from: Text mode, Prog mode, and Special
- mode. While Text mode is useful in its own right (e.g. for editing
- files ending in `.txt'), Prog mode and Special mode exist mainly to let
- other modes derive from them.
- As far as possible, new major modes should be derived, either
- directly or indirectly, from one of these three modes. One reason is
- that this allows users to customize a single mode hook (e.g.
- `prog-mode-hook') for an entire family of relevant modes (e.g. all
- programming language modes).
- -- Command: text-mode
- Text mode is a major mode for editing human languages. It defines
- the `"' and `\' characters as having punctuation syntax (*note
- Syntax Class Table::), and binds `M-<TAB>' to
- `ispell-complete-word' (*note Spelling: (emacs)Spelling.).
- An example of a major mode derived from Text mode is HTML mode.
- *Note SGML and HTML Modes: (emacs)HTML Mode.
- -- Command: prog-mode
- Prog mode is a basic major mode for buffers containing programming
- language source code. Most of the programming language major modes
- built into Emacs are derived from it.
- Prog mode binds `parse-sexp-ignore-comments' to `t' (*note Motion
- via Parsing::) and `bidi-paragraph-direction' to `left-to-right'
- (*note Bidirectional Display::).
- -- Command: special-mode
- Special mode is a basic major mode for buffers containing text
- that is produced specially by Emacs, rather than directly from a
- file. Major modes derived from Special mode are given a
- `mode-class' property of `special' (*note Major Mode
- Conventions::).
- Special mode sets the buffer to read-only. Its keymap defines
- several common bindings, including `q' for `quit-window', `z' for
- `kill-this-buffer', and `g' for `revert-buffer' (*note
- Reverting::).
- An example of a major mode derived from Special mode is Buffer Menu
- mode, which is used by the `*Buffer List*' buffer. *Note Listing
- Existing Buffers: (emacs)List Buffers.
- In addition, modes for buffers of tabulated data can inherit from
- Tabulated List mode, which is in turn derived from Special mode. *Note
- Tabulated List Mode::.
- File: elisp, Node: Mode Hooks, Next: Tabulated List Mode, Prev: Basic Major Modes, Up: Major Modes
- 23.2.6 Mode Hooks
- -----------------
- Every major mode command should finish by running the mode-independent
- normal hook `change-major-mode-after-body-hook', its mode hook, and the
- normal hook `after-change-major-mode-hook'. It does this by calling
- `run-mode-hooks'. If the major mode is a derived mode, that is if it
- calls another major mode (the parent mode) in its body, it should do
- this inside `delay-mode-hooks' so that the parent won't run these hooks
- itself. Instead, the derived mode's call to `run-mode-hooks' runs the
- parent's mode hook too. *Note Major Mode Conventions::.
- Emacs versions before Emacs 22 did not have `delay-mode-hooks'.
- Versions before 24 did not have `change-major-mode-after-body-hook'.
- When user-implemented major modes do not use `run-mode-hooks' and have
- not been updated to use these newer features, they won't entirely
- follow these conventions: they may run the parent's mode hook too early,
- or fail to run `after-change-major-mode-hook'. If you encounter such a
- major mode, please correct it to follow these conventions.
- When you defined a major mode using `define-derived-mode', it
- automatically makes sure these conventions are followed. If you define
- a major mode "by hand", not using `define-derived-mode', use the
- following functions to handle these conventions automatically.
- -- Function: run-mode-hooks &rest hookvars
- Major modes should run their mode hook using this function. It is
- similar to `run-hooks' (*note Hooks::), but it also runs
- `change-major-mode-after-body-hook' and
- `after-change-major-mode-hook'.
- When this function is called during the execution of a
- `delay-mode-hooks' form, it does not run the hooks immediately.
- Instead, it arranges for the next call to `run-mode-hooks' to run
- them.
- -- Macro: delay-mode-hooks body...
- When one major mode command calls another, it should do so inside
- of `delay-mode-hooks'.
- This macro executes BODY, but tells all `run-mode-hooks' calls
- during the execution of BODY to delay running their hooks. The
- hooks will actually run during the next call to `run-mode-hooks'
- after the end of the `delay-mode-hooks' construct.
- -- Variable: change-major-mode-after-body-hook
- This is a normal hook run by `run-mode-hooks'. It is run before
- the mode hooks.
- -- Variable: after-change-major-mode-hook
- This is a normal hook run by `run-mode-hooks'. It is run at the
- very end of every properly-written major mode command.
- File: elisp, Node: Tabulated List Mode, Next: Generic Modes, Prev: Mode Hooks, Up: Major Modes
- 23.2.7 Tabulated List mode
- --------------------------
- Tabulated List mode is a major mode for displaying tabulated data, i.e.
- data consisting of "entries", each entry occupying one row of text with
- its contents divided into columns. Tabulated List mode provides
- facilities for pretty-printing rows and columns, and sorting the rows
- according to the values in each column. It is derived from Special
- mode (*note Basic Major Modes::).
- Tabulated List mode is intended to be used as a parent mode by a more
- specialized major mode. Examples include Process Menu mode (*note
- Process Information::) and Package Menu mode (*note Package Menu:
- (emacs)Package Menu.).
- Such a derived mode should use `define-derived-mode' in the usual
- way, specifying `tabulated-list-mode' as the second argument (*note
- Derived Modes::). The body of the `define-derived-mode' form should
- specify the format of the tabulated data, by assigning values to the
- variables documented below; then, it should call the function
- `tabulated-list-init-header' to initialize the header line.
- The derived mode should also define a "listing command". This, not
- the mode command, is what the user calls (e.g. `M-x list-processes').
- The listing command should create or switch to a buffer, turn on the
- derived mode, specify the tabulated data, and finally call
- `tabulated-list-print' to populate the buffer.
- -- Variable: tabulated-list-format
- This buffer-local variable specifies the format of the Tabulated
- List data. Its value should be a vector. Each element of the
- vector represents a data column, and should be a list `(NAME WIDTH
- SORT)', where
- * NAME is the column's name (a string).
- * WIDTH is the width to reserve for the column (an integer).
- This is meaningless for the last column, which runs to the
- end of each line.
- * SORT specifies how to sort entries by the column. If `nil',
- the column cannot be used for sorting. If `t', the column is
- sorted by comparing string values. Otherwise, this should be
- a predicate function for `sort' (*note Rearrangement::), which
- accepts two arguments with the same form as the elements of
- `tabulated-list-entries' (see below).
- -- Variable: tabulated-list-entries
- This buffer-local variable specifies the entries displayed in the
- Tabulated List buffer. Its value should be either a list, or a
- function.
- If the value is a list, each list element corresponds to one
- entry, and should have the form `(ID CONTENTS)', where
- * ID is either `nil', or a Lisp object that identifies the
- entry. If the latter, the cursor stays on the "same" entry
- when re-sorting entries. Comparison is done with `equal'.
- * CONTENTS is a vector with the same number of elements as
- `tabulated-list-format'. Each vector element is either a
- string, which is inserted into the buffer as-is, or a list
- `(LABEL . PROPERTIES)', which means to insert a text button
- by calling `insert-text-button' with LABEL and PROPERTIES as
- arguments (*note Making Buttons::).
- There should be no newlines in any of these strings.
- Otherwise, the value should be a function which returns a list of
- the above form when called with no arguments.
- -- Variable: tabulated-list-revert-hook
- This normal hook is run prior to reverting a Tabulated List
- buffer. A derived mode can add a function to this hook to
- recompute `tabulated-list-entries'.
- -- Variable: tabulated-list-printer
- The value of this variable is the function called to insert an
- entry at point, including its terminating newline. The function
- should accept two arguments, ID and CONTENTS, having the same
- meanings as in `tabulated-list-entries'. The default value is a
- function which inserts an entry in a straightforward way; a mode
- which uses Tabulated List mode in a more complex way can specify
- another function.
- -- Variable: tabulated-list-sort-key
- The value of this variable specifies the current sort key for the
- Tabulated List buffer. If it is `nil', no sorting is done.
- Otherwise, it should have the form `(NAME . FLIP)', where NAME is
- a string matching one of the column names in
- `tabulated-list-format', and FLIP, if non-`nil', means to invert
- the sort order.
- -- Function: tabulated-list-init-header
- This function computes and sets `header-line-format' for the
- Tabulated List buffer (*note Header Lines::), and assigns a keymap
- to the header line to allow sort entries by clicking on column
- headers.
- Modes derived from Tabulated List mode should call this after
- setting the above variables (in particular, only after setting
- `tabulated-list-format').
- -- Function: tabulated-list-print &optional remember-pos
- This function populates the current buffer with entries. It
- should be called by the listing command. It erases the buffer,
- sorts the entries specified by `tabulated-list-entries' according
- to `tabulated-list-sort-key', then calls the function specified by
- `tabulated-list-printer' to insert each entry.
- If the optional argument REMEMBER-POS is non-`nil', this function
- looks for the ID element on the current line, if any, and tries to
- move to that entry after all the entries are (re)inserted.
- File: elisp, Node: Generic Modes, Next: Example Major Modes, Prev: Tabulated List Mode, Up: Major Modes
- 23.2.8 Generic Modes
- --------------------
- "Generic modes" are simple major modes with basic support for comment
- syntax and Font Lock mode. To define a generic mode, use the macro
- `define-generic-mode'. See the file `generic-x.el' for some examples
- of the use of `define-generic-mode'.
- -- Macro: define-generic-mode mode comment-list keyword-list
- font-lock-list auto-mode-list function-list &optional
- docstring
- This macro defines a generic mode command named MODE (a symbol,
- not quoted). The optional argument DOCSTRING is the documentation
- for the mode command. If you do not supply it,
- `define-generic-mode' generates one by default.
- The argument COMMENT-LIST is a list in which each element is
- either a character, a string of one or two characters, or a cons
- cell. A character or a string is set up in the mode's syntax
- table as a "comment starter". If the entry is a cons cell, the
- CAR is set up as a "comment starter" and the CDR as a "comment
- ender". (Use `nil' for the latter if you want comments to end at
- the end of the line.) Note that the syntax table mechanism has
- limitations about what comment starters and enders are actually
- possible. *Note Syntax Tables::.
- The argument KEYWORD-LIST is a list of keywords to highlight with
- `font-lock-keyword-face'. Each keyword should be a string.
- Meanwhile, FONT-LOCK-LIST is a list of additional expressions to
- highlight. Each element of this list should have the same form as
- an element of `font-lock-keywords'. *Note Search-based
- Fontification::.
- The argument AUTO-MODE-LIST is a list of regular expressions to
- add to the variable `auto-mode-alist'. They are added by the
- execution of the `define-generic-mode' form, not by expanding the
- macro call.
- Finally, FUNCTION-LIST is a list of functions for the mode command
- to call for additional setup. It calls these functions just
- before it runs the mode hook variable `MODE-hook'.
- File: elisp, Node: Example Major Modes, Prev: Generic Modes, Up: Major Modes
- 23.2.9 Major Mode Examples
- --------------------------
- Text mode is perhaps the simplest mode besides Fundamental mode. Here
- are excerpts from `text-mode.el' that illustrate many of the
- conventions listed above:
- ;; Create the syntax table for this mode.
- (defvar text-mode-syntax-table
- (let ((st (make-syntax-table)))
- (modify-syntax-entry ?\" ". " st)
- (modify-syntax-entry ?\\ ". " st)
- ;; Add `p' so M-c on `hello' leads to `Hello', not `hello'.
- (modify-syntax-entry ?' "w p" st)
- st)
- "Syntax table used while in `text-mode'.")
- ;; Create the keymap for this mode.
- (defvar text-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map "\e\t" 'ispell-complete-word)
- map)
- "Keymap for `text-mode'.
- Many other modes, such as `mail-mode', `outline-mode' and
- `indented-text-mode', inherit all the commands defined in this map.")
- Here is how the actual mode command is defined now:
- (define-derived-mode text-mode nil "Text"
- "Major mode for editing text written for humans to read.
- In this mode, paragraphs are delimited only by blank or white lines.
- You can thus get the full benefit of adaptive filling
- (see the variable `adaptive-fill-mode').
- \\{text-mode-map}
- Turning on Text mode runs the normal hook `text-mode-hook'."
- (set (make-local-variable 'text-mode-variant) t)
- (set (make-local-variable 'require-final-newline)
- mode-require-final-newline)
- (set (make-local-variable 'indent-line-function) 'indent-relative))
- (The last line is redundant nowadays, since `indent-relative' is the
- default value, and we'll delete it in a future version.)
- The three Lisp modes (Lisp mode, Emacs Lisp mode, and Lisp
- Interaction mode) have more features than Text mode and the code is
- correspondingly more complicated. Here are excerpts from
- `lisp-mode.el' that illustrate how these modes are written.
- Here is how the Lisp mode syntax and abbrev tables are defined:
- ;; Create mode-specific table variables.
- (defvar lisp-mode-abbrev-table nil)
- (define-abbrev-table 'lisp-mode-abbrev-table ())
- (defvar lisp-mode-syntax-table
- (let ((table (copy-syntax-table emacs-lisp-mode-syntax-table)))
- (modify-syntax-entry ?\[ "_ " table)
- (modify-syntax-entry ?\] "_ " table)
- (modify-syntax-entry ?# "' 14" table)
- (modify-syntax-entry ?| "\" 23bn" table)
- table)
- "Syntax table used in `lisp-mode'.")
- The three modes for Lisp share much of their code. For instance,
- each calls the following function to set various variables:
- (defun lisp-mode-variables (&optional syntax keywords-case-insensitive)
- (when syntax
- (set-syntax-table lisp-mode-syntax-table))
- (setq local-abbrev-table lisp-mode-abbrev-table)
- ...
- Amongst other things, this function sets up the `comment-start'
- variable to handle Lisp comments:
- (make-local-variable 'comment-start)
- (setq comment-start ";")
- ...
- Each of the different Lisp modes has a slightly different keymap.
- For example, Lisp mode binds `C-c C-z' to `run-lisp', but the other
- Lisp modes do not. However, all Lisp modes have some commands in
- common. The following code sets up the common commands:
- (defvar lisp-mode-shared-map
- (let ((map (make-sparse-keymap)))
- (define-key map "\e\C-q" 'indent-sexp)
- (define-key map "\177" 'backward-delete-char-untabify)
- map)
- "Keymap for commands shared by all sorts of Lisp modes.")
- And here is the code to set up the keymap for Lisp mode:
- (defvar lisp-mode-map
- (let ((map (make-sparse-keymap))
- (menu-map (make-sparse-keymap "Lisp")))
- (set-keymap-parent map lisp-mode-shared-map)
- (define-key map "\e\C-x" 'lisp-eval-defun)
- (define-key map "\C-c\C-z" 'run-lisp)
- ...
- map)
- "Keymap for ordinary Lisp mode.
- All commands in `lisp-mode-shared-map' are inherited by this map.")
- Finally, here is the major mode command for Lisp mode:
- (define-derived-mode lisp-mode prog-mode "Lisp"
- "Major mode for editing Lisp code for Lisps other than GNU Emacs Lisp.
- Commands:
- Delete converts tabs to spaces as it moves back.
- Blank lines separate paragraphs. Semicolons start comments.
- \\{lisp-mode-map}
- Note that `run-lisp' may be used either to start an inferior Lisp job
- or to switch back to an existing one.
- Entry to this mode calls the value of `lisp-mode-hook'
- if that value is non-nil."
- (lisp-mode-variables nil t)
- (set (make-local-variable 'find-tag-default-function)
- 'lisp-find-tag-default)
- (set (make-local-variable 'comment-start-skip)
- "\\(\\(^\\|[^\\\\\n]\\)\\(\\\\\\\\\\)*\\)\\(;+\\|#|\\) *")
- (setq imenu-case-fold-search t))
- File: elisp, Node: Minor Modes, Next: Mode Line Format, Prev: Major Modes, Up: Modes
- 23.3 Minor Modes
- ================
- A "minor mode" provides optional features that users may enable or
- disable independently of the choice of major mode. Minor modes can be
- enabled individually or in combination.
- Most minor modes implement features that are independent of the major
- mode, and can thus be used with most major modes. For example, Auto
- Fill mode works with any major mode that permits text insertion. A few
- minor modes, however, are specific to a particular major mode. For
- example, Diff Auto Refine mode is a minor mode that is intended to be
- used only with Diff mode.
- Ideally, a minor mode should have its desired effect regardless of
- the other minor modes in effect. It should be possible to activate and
- deactivate minor modes in any order.
- -- Variable: minor-mode-list
- The value of this variable is a list of all minor mode commands.
- * Menu:
- * Minor Mode Conventions:: Tips for writing a minor mode.
- * Keymaps and Minor Modes:: How a minor mode can have its own keymap.
- * Defining Minor Modes:: A convenient facility for defining minor modes.
- File: elisp, Node: Minor Mode Conventions, Next: Keymaps and Minor Modes, Up: Minor Modes
- 23.3.1 Conventions for Writing Minor Modes
- ------------------------------------------
- There are conventions for writing minor modes just as there are for
- major modes. These conventions are described below. The easiest way to
- follow them is to use the macro `define-minor-mode'. *Note Defining
- Minor Modes::.
- * Define a variable whose name ends in `-mode'. We call this the
- "mode variable". The minor mode command should set this variable.
- The value will be `nil' is the mode is disabled, and non-`nil' if
- the mode is enabled. The variable should be buffer-local if the
- minor mode is buffer-local.
- This variable is used in conjunction with the `minor-mode-alist' to
- display the minor mode name in the mode line. It also determines
- whether the minor mode keymap is active, via `minor-mode-map-alist'
- (*note Controlling Active Maps::). Individual commands or hooks
- can also check its value.
- * Define a command, called the "mode command", whose name is the same
- as the mode variable. Its job is to set the value of the mode
- variable, plus anything else that needs to be done to actually
- enable or disable the mode's features.
- The mode command should accept one optional argument. If called
- interactively with no prefix argument, it should toggle the mode
- (i.e. enable if it is disabled, and disable if it is enabled). If
- called interactively with a prefix argument, it should enable the
- mode if the argument is positive and disable it otherwise.
- If the mode command is called from Lisp (i.e. non-interactively),
- it should enable the mode if the argument is omitted or `nil'; it
- should toggle the mode if the argument is the symbol `toggle';
- otherwise it should treat the argument in the same way as for an
- interactive call with a numeric prefix argument, as described
- above.
- The following example shows how to implement this behavior (it is
- similar to the code generated by the `define-minor-mode' macro):
- (interactive (list (or current-prefix-arg 'toggle)))
- (let ((enable (if (eq arg 'toggle)
- (not foo-mode) ; this mode's mode variable
- (> (prefix-numeric-value arg) 0))))
- (if enable
- DO-ENABLE
- DO-DISABLE))
- The reason for this somewhat complex behavior is that it lets users
- easily toggle the minor mode interactively, and also lets the
- minor mode be easily enabled in a mode hook, like this:
- (add-hook 'text-mode-hook 'foo-mode)
- This behaves correctly whether or not `foo-mode' was already
- enabled, since the `foo-mode' mode command unconditionally enables
- the minor mode when it is called from Lisp with no argument.
- Disabling a minor mode in a mode hook is a little uglier:
- (add-hook 'text-mode-hook (lambda () (foo-mode -1)))
- However, this is not very commonly done.
- * Add an element to `minor-mode-alist' for each minor mode (*note
- Definition of minor-mode-alist::), if you want to indicate the
- minor mode in the mode line. This element should be a list of the
- following form:
- (MODE-VARIABLE STRING)
- Here MODE-VARIABLE is the variable that controls enabling of the
- minor mode, and STRING is a short string, starting with a space,
- to represent the mode in the mode line. These strings must be
- short so that there is room for several of them at once.
- When you add an element to `minor-mode-alist', use `assq' to check
- for an existing element, to avoid duplication. For example:
- (unless (assq 'leif-mode minor-mode-alist)
- (push '(leif-mode " Leif") minor-mode-alist))
- or like this, using `add-to-list' (*note List Variables::):
- (add-to-list 'minor-mode-alist '(leif-mode " Leif"))
- In addition, several major mode conventions apply to minor modes as
- well: those regarding the names of global symbols, the use of a hook at
- the end of the initialization function, and the use of keymaps and other
- tables.
- The minor mode should, if possible, support enabling and disabling
- via Custom (*note Customization::). To do this, the mode variable
- should be defined with `defcustom', usually with `:type 'boolean'. If
- just setting the variable is not sufficient to enable the mode, you
- should also specify a `:set' method which enables the mode by invoking
- the mode command. Note in the variable's documentation string that
- setting the variable other than via Custom may not take effect. Also,
- mark the definition with an autoload cookie (*note autoload cookie::),
- and specify a `:require' so that customizing the variable will load the
- library that defines the mode. For example:
- ;;;###autoload
- (defcustom msb-mode nil
- "Toggle msb-mode.
- Setting this variable directly does not take effect;
- use either \\[customize] or the function `msb-mode'."
- :set 'custom-set-minor-mode
- :initialize 'custom-initialize-default
- :version "20.4"
- :type 'boolean
- :group 'msb
- :require 'msb)
- File: elisp, Node: Keymaps and Minor Modes, Next: Defining Minor Modes, Prev: Minor Mode Conventions, Up: Minor Modes
- 23.3.2 Keymaps and Minor Modes
- ------------------------------
- Each minor mode can have its own keymap, which is active when the mode
- is enabled. To set up a keymap for a minor mode, add an element to the
- alist `minor-mode-map-alist'. *Note Definition of
- minor-mode-map-alist::.
- One use of minor mode keymaps is to modify the behavior of certain
- self-inserting characters so that they do something else as well as
- self-insert. (Another way to customize `self-insert-command' is
- through `post-self-insert-hook'. Apart from this, the facilities for
- customizing `self-insert-command' are limited to special cases,
- designed for abbrevs and Auto Fill mode. Do not try substituting your
- own definition of `self-insert-command' for the standard one. The
- editor command loop handles this function specially.)
- The key sequences bound in a minor mode should consist of `C-c'
- followed by one of `.,/?`'"[]\|~!#$%^&*()-_+='. (The other punctuation
- characters are reserved for major modes.)
- File: elisp, Node: Defining Minor Modes, Prev: Keymaps and Minor Modes, Up: Minor Modes
- 23.3.3 Defining Minor Modes
- ---------------------------
- The macro `define-minor-mode' offers a convenient way of implementing a
- mode in one self-contained definition.
- -- Macro: define-minor-mode mode doc [init-value [lighter [keymap]]]
- keyword-args... body...
- This macro defines a new minor mode whose name is MODE (a symbol).
- It defines a command named MODE to toggle the minor mode, with DOC
- as its documentation string.
- The toggle command takes one optional (prefix) argument. If
- called interactively with no argument it toggles the mode on or
- off. A positive prefix argument enables the mode, any other
- prefix argument disables it. From Lisp, an argument of `toggle'
- toggles the mode, whereas an omitted or `nil' argument enables the
- mode. This makes it easy to enable the minor mode in a major mode
- hook, for example. If DOC is nil, the macro supplies a default
- documentation string explaining the above.
- By default, it also defines a variable named MODE, which is set to
- `t' or `nil' by enabling or disabling the mode. The variable is
- initialized to INIT-VALUE. Except in unusual circumstances (see
- below), this value must be `nil'.
- The string LIGHTER says what to display in the mode line when the
- mode is enabled; if it is `nil', the mode is not displayed in the
- mode line.
- The optional argument KEYMAP specifies the keymap for the minor
- mode. If non-`nil', it should be a variable name (whose value is
- a keymap), a keymap, or an alist of the form
- (KEY-SEQUENCE . DEFINITION)
- where each KEY-SEQUENCE and DEFINITION are arguments suitable for
- passing to `define-key' (*note Changing Key Bindings::). If
- KEYMAP is a keymap or an alist, this also defines the variable
- `MODE-map'.
- The above three arguments INIT-VALUE, LIGHTER, and KEYMAP can be
- (partially) omitted when KEYWORD-ARGS are used. The KEYWORD-ARGS
- consist of keywords followed by corresponding values. A few
- keywords have special meanings:
- `:group GROUP'
- Custom group name to use in all generated `defcustom' forms.
- Defaults to MODE without the possible trailing `-mode'.
- *Warning:* don't use this default group name unless you have
- written a `defgroup' to define that group properly. *Note
- Group Definitions::.
- `:global GLOBAL'
- If non-`nil', this specifies that the minor mode should be
- global rather than buffer-local. It defaults to `nil'.
- One of the effects of making a minor mode global is that the
- MODE variable becomes a customization variable. Toggling it
- through the Customize interface turns the mode on and off,
- and its value can be saved for future Emacs sessions (*note
- Saving Customizations: (emacs)Saving Customizations. For the
- saved variable to work, you should ensure that the
- `define-minor-mode' form is evaluated each time Emacs starts;
- for packages that are not part of Emacs, the easiest way to
- do this is to specify a `:require' keyword.
- `:init-value INIT-VALUE'
- This is equivalent to specifying INIT-VALUE positionally.
- `:lighter LIGHTER'
- This is equivalent to specifying LIGHTER positionally.
- `:keymap KEYMAP'
- This is equivalent to specifying KEYMAP positionally.
- `:variable PLACE'
- This replaces the default variable MODE, used to store the
- state of the mode. If you specify this, the MODE variable is
- not defined, and any INIT-VALUE argument is unused. PLACE
- can be a different named variable (which you must define
- yourself), or anything that can be used with the `setf'
- function (*note Generalized Variables: (cl)Generalized
- Variables.). PLACE can also be a cons `(GET . SET)', where
- GET is an expression that returns the current state, and SET
- is a function of one argument (a state) that sets it.
- `:after-hook AFTER-HOOK'
- This defines a single Lisp form which is evaluated after the
- mode hooks have run. It should not be quoted.
- Any other keyword arguments are passed directly to the `defcustom'
- generated for the variable MODE.
- The command named MODE first performs the standard actions such as
- setting the variable named MODE and then executes the BODY forms,
- if any. It then runs the mode hook variable `MODE-hook' and
- finishes by evaluating any form in `:after-hook'.
- The initial value must be `nil' except in cases where (1) the mode
- is preloaded in Emacs, or (2) it is painless for loading to enable the
- mode even though the user did not request it. For instance, if the
- mode has no effect unless something else is enabled, and will always be
- loaded by that time, enabling it by default is harmless. But these are
- unusual circumstances. Normally, the initial value must be `nil'.
- The name `easy-mmode-define-minor-mode' is an alias for this macro.
- Here is an example of using `define-minor-mode':
- (define-minor-mode hungry-mode
- "Toggle Hungry mode.
- Interactively with no argument, this command toggles the mode.
- A positive prefix argument enables the mode, any other prefix
- argument disables it. From Lisp, argument omitted or nil enables
- the mode, `toggle' toggles the state.
- When Hungry mode is enabled, the control delete key
- gobbles all preceding whitespace except the last.
- See the command \\[hungry-electric-delete]."
- ;; The initial value.
- nil
- ;; The indicator for the mode line.
- " Hungry"
- ;; The minor mode bindings.
- '(([C-backspace] . hungry-electric-delete))
- :group 'hunger)
- This defines a minor mode named "Hungry mode", a command named
- `hungry-mode' to toggle it, a variable named `hungry-mode' which
- indicates whether the mode is enabled, and a variable named
- `hungry-mode-map' which holds the keymap that is active when the mode
- is enabled. It initializes the keymap with a key binding for
- `C-<DEL>'. It puts the variable `hungry-mode' into custom group
- `hunger'. There are no BODY forms--many minor modes don't need any.
- Here's an equivalent way to write it:
- (define-minor-mode hungry-mode
- "Toggle Hungry mode.
- ...rest of documentation as before..."
- ;; The initial value.
- :init-value nil
- ;; The indicator for the mode line.
- :lighter " Hungry"
- ;; The minor mode bindings.
- :keymap
- '(([C-backspace] . hungry-electric-delete)
- ([C-M-backspace]
- . (lambda ()
- (interactive)
- (hungry-electric-delete t))))
- :group 'hunger)
- -- Macro: define-globalized-minor-mode global-mode mode turn-on
- keyword-args...
- This defines a global toggle named GLOBAL-MODE whose meaning is to
- enable or disable the buffer-local minor mode MODE in all buffers.
- To turn on the minor mode in a buffer, it uses the function
- TURN-ON; to turn off the minor mode, it calls `mode' with -1 as
- argument.
- Globally enabling the mode also affects buffers subsequently
- created by visiting files, and buffers that use a major mode other
- than Fundamental mode; but it does not detect the creation of a
- new buffer in Fundamental mode.
- This defines the customization option GLOBAL-MODE (*note
- Customization::), which can be toggled in the Customize interface
- to turn the minor mode on and off. As with `define-minor-mode',
- you should ensure that the `define-globalized-minor-mode' form is
- evaluated each time Emacs starts, for example by providing a
- `:require' keyword.
- Use `:group GROUP' in KEYWORD-ARGS to specify the custom group for
- the mode variable of the global minor mode.
- Generally speaking, when you define a globalized minor mode, you
- should also define a non-globalized version, so that people can
- use (or disable) it in individual buffers. This also allows them
- to disable a globally enabled minor mode in a specific major mode,
- by using that mode's hook.
- File: elisp, Node: Mode Line Format, Next: Imenu, Prev: Minor Modes, Up: Modes
- 23.4 Mode Line Format
- =====================
- Each Emacs window (aside from minibuffer windows) typically has a mode
- line at the bottom, which displays status information about the buffer
- displayed in the window. The mode line contains information about the
- buffer, such as its name, associated file, depth of recursive editing,
- and major and minor modes. A window can also have a "header line",
- which is much like the mode line but appears at the top of the window.
- This section describes how to control the contents of the mode line
- and header line. We include it in this chapter because much of the
- information displayed in the mode line relates to the enabled major and
- minor modes.
- * Menu:
- * Base: Mode Line Basics. Basic ideas of mode line control.
- * Data: Mode Line Data. The data structure that controls the mode line.
- * Top: Mode Line Top. The top level variable, mode-line-format.
- * Mode Line Variables:: Variables used in that data structure.
- * %-Constructs:: Putting information into a mode line.
- * Properties in Mode:: Using text properties in the mode line.
- * Header Lines:: Like a mode line, but at the top.
- * Emulating Mode Line:: Formatting text as the mode line would.
- File: elisp, Node: Mode Line Basics, Next: Mode Line Data, Up: Mode Line Format
- 23.4.1 Mode Line Basics
- -----------------------
- The contents of each mode line are specified by the buffer-local
- variable `mode-line-format' (*note Mode Line Top::). This variable
- holds a "mode line construct": a template that controls what is
- displayed on the buffer's mode line. The value of `header-line-format'
- specifies the buffer's header line in the same way. All windows for
- the same buffer use the same `mode-line-format' and
- `header-line-format'.
- For efficiency, Emacs does not continuously recompute each window's
- mode line and header line. It does so when circumstances appear to call
- for it--for instance, if you change the window configuration, switch
- buffers, narrow or widen the buffer, scroll, or modify the buffer. If
- you alter any of the variables referenced by `mode-line-format' or
- `header-line-format' (*note Mode Line Variables::), or any other data
- structures that affect how text is displayed (*note Display::), you
- should use the function `force-mode-line-update' to update the display.
- -- Function: force-mode-line-update &optional all
- This function forces Emacs to update the current buffer's mode
- line and header line, based on the latest values of all relevant
- variables, during its next redisplay cycle. If the optional
- argument ALL is non-`nil', it forces an update for all mode lines
- and header lines.
- This function also forces an update of the menu bar and frame
- title.
- The selected window's mode line is usually displayed in a different
- color using the face `mode-line'. Other windows' mode lines appear in
- the face `mode-line-inactive' instead. *Note Faces::.
- File: elisp, Node: Mode Line Data, Next: Mode Line Top, Prev: Mode Line Basics, Up: Mode Line Format
- 23.4.2 The Data Structure of the Mode Line
- ------------------------------------------
- The mode line contents are controlled by a data structure called a
- "mode line construct", made up of lists, strings, symbols, and numbers
- kept in buffer-local variables. Each data type has a specific meaning
- for the mode line appearance, as described below. The same data
- structure is used for constructing frame titles (*note Frame Titles::)
- and header lines (*note Header Lines::).
- A mode line construct may be as simple as a fixed string of text,
- but it usually specifies how to combine fixed strings with variables'
- values to construct the text. Many of these variables are themselves
- defined to have mode line constructs as their values.
- Here are the meanings of various data types as mode line constructs:
- `STRING'
- A string as a mode line construct appears verbatim except for
- "`%'-constructs" in it. These stand for substitution of other
- data; see *note %-Constructs::.
- If parts of the string have `face' properties, they control
- display of the text just as they would text in the buffer. Any
- characters which have no `face' properties are displayed, by
- default, in the face `mode-line' or `mode-line-inactive' (*note
- Standard Faces: (emacs)Standard Faces.). The `help-echo' and
- `local-map' properties in STRING have special meanings. *Note
- Properties in Mode::.
- `SYMBOL'
- A symbol as a mode line construct stands for its value. The value
- of SYMBOL is used as a mode line construct, in place of SYMBOL.
- However, the symbols `t' and `nil' are ignored, as is any symbol
- whose value is void.
- There is one exception: if the value of SYMBOL is a string, it is
- displayed verbatim: the `%'-constructs are not recognized.
- Unless SYMBOL is marked as "risky" (i.e., it has a non-`nil'
- `risky-local-variable' property), all text properties specified in
- SYMBOL's value are ignored. This includes the text properties of
- strings in SYMBOL's value, as well as all `:eval' and
- `:propertize' forms in it. (The reason for this is security:
- non-risky variables could be set automatically from file variables
- without prompting the user.)
- `(STRING REST...)'
- `(LIST REST...)'
- A list whose first element is a string or list means to process
- all the elements recursively and concatenate the results. This is
- the most common form of mode line construct.
- `(:eval FORM)'
- A list whose first element is the symbol `:eval' says to evaluate
- FORM, and use the result as a string to display. Make sure this
- evaluation cannot load any files, as doing so could cause infinite
- recursion.
- `(:propertize ELT PROPS...)'
- A list whose first element is the symbol `:propertize' says to
- process the mode line construct ELT recursively, then add the text
- properties specified by PROPS to the result. The argument PROPS
- should consist of zero or more pairs TEXT-PROPERTY VALUE.
- `(SYMBOL THEN ELSE)'
- A list whose first element is a symbol that is not a keyword
- specifies a conditional. Its meaning depends on the value of
- SYMBOL. If SYMBOL has a non-`nil' value, the second element,
- THEN, is processed recursively as a mode line element. Otherwise,
- the third element, ELSE, is processed recursively. You may omit
- ELSE; then the mode line element displays nothing if the value of
- SYMBOL is `nil' or void.
- `(WIDTH REST...)'
- A list whose first element is an integer specifies truncation or
- padding of the results of REST. The remaining elements REST are
- processed recursively as mode line constructs and concatenated
- together. When WIDTH is positive, the result is space filled on
- the right if its width is less than WIDTH. When WIDTH is
- negative, the result is truncated on the right to -WIDTH columns
- if its width exceeds -WIDTH.
- For example, the usual way to show what percentage of a buffer is
- above the top of the window is to use a list like this: `(-3
- "%p")'.
- File: elisp, Node: Mode Line Top, Next: Mode Line Variables, Prev: Mode Line Data, Up: Mode Line Format
- 23.4.3 The Top Level of Mode Line Control
- -----------------------------------------
- The variable in overall control of the mode line is `mode-line-format'.
- -- User Option: mode-line-format
- The value of this variable is a mode line construct that controls
- the contents of the mode-line. It is always buffer-local in all
- buffers.
- If you set this variable to `nil' in a buffer, that buffer does not
- have a mode line. (A window that is just one line tall also does
- not display a mode line.)
- The default value of `mode-line-format' is designed to use the
- values of other variables such as `mode-line-position' and
- `mode-line-modes' (which in turn incorporates the values of the
- variables `mode-name' and `minor-mode-alist'). Very few modes need to
- alter `mode-line-format' itself. For most purposes, it is sufficient
- to alter some of the variables that `mode-line-format' either directly
- or indirectly refers to.
- If you do alter `mode-line-format' itself, the new value should use
- the same variables that appear in the default value (*note Mode Line
- Variables::), rather than duplicating their contents or displaying the
- information in another fashion. This way, customizations made by the
- user or by Lisp programs (such as `display-time' and major modes) via
- changes to those variables remain effective.
- Here is a hypothetical example of a `mode-line-format' that might be
- useful for Shell mode (in reality, Shell mode does not set
- `mode-line-format'):
- (setq mode-line-format
- (list "-"
- 'mode-line-mule-info
- 'mode-line-modified
- 'mode-line-frame-identification
- "%b--"
- ;; Note that this is evaluated while making the list.
- ;; It makes a mode line construct which is just a string.
- (getenv "HOST")
- ":"
- 'default-directory
- " "
- 'global-mode-string
- " %[("
- '(:eval (mode-line-mode-name))
- 'mode-line-process
- 'minor-mode-alist
- "%n"
- ")%]--"
- '(which-func-mode ("" which-func-format "--"))
- '(line-number-mode "L%l--")
- '(column-number-mode "C%c--")
- '(-3 "%p")))
- (The variables `line-number-mode', `column-number-mode' and
- `which-func-mode' enable particular minor modes; as usual, these
- variable names are also the minor mode command names.)
- File: elisp, Node: Mode Line Variables, Next: %-Constructs, Prev: Mode Line Top, Up: Mode Line Format
- 23.4.4 Variables Used in the Mode Line
- --------------------------------------
- This section describes variables incorporated by the standard value of
- `mode-line-format' into the text of the mode line. There is nothing
- inherently special about these variables; any other variables could
- have the same effects on the mode line if the value of
- `mode-line-format' is changed to use them. However, various parts of
- Emacs set these variables on the understanding that they will control
- parts of the mode line; therefore, practically speaking, it is essential
- for the mode line to use them.
- -- Variable: mode-line-mule-info
- This variable holds the value of the mode line construct that
- displays information about the language environment, buffer coding
- system, and current input method. *Note Non-ASCII Characters::.
- -- Variable: mode-line-modified
- This variable holds the value of the mode line construct that
- displays whether the current buffer is modified. Its default
- value displays `**' if the buffer is modified, `--' if the buffer
- is not modified, `%%' if the buffer is read only, and `%*' if the
- buffer is read only and modified.
- Changing this variable does not force an update of the mode line.
- -- Variable: mode-line-frame-identification
- This variable identifies the current frame. Its default value
- displays `" "' if you are using a window system which can show
- multiple frames, or `"-%F "' on an ordinary terminal which shows
- only one frame at a time.
- -- Variable: mode-line-buffer-identification
- This variable identifies the buffer being displayed in the window.
- Its default value displays the buffer name, padded with spaces to
- at least 12 columns.
- -- User Option: mode-line-position
- This variable indicates the position in the buffer. Its default
- value displays the buffer percentage and, optionally, the buffer
- size, the line number and the column number.
- -- Variable: vc-mode
- The variable `vc-mode', buffer-local in each buffer, records
- whether the buffer's visited file is maintained with version
- control, and, if so, which kind. Its value is a string that
- appears in the mode line, or `nil' for no version control.
- -- User Option: mode-line-modes
- This variable displays the buffer's major and minor modes. Its
- default value also displays the recursive editing level,
- information on the process status, and whether narrowing is in
- effect.
- -- Variable: mode-line-remote
- This variable is used to show whether `default-directory' for the
- current buffer is remote.
- -- Variable: mode-line-client
- This variable is used to identify `emacsclient' frames.
- The following three variables are used in `mode-line-modes':
- -- Variable: mode-name
- This buffer-local variable holds the "pretty" name of the current
- buffer's major mode. Each major mode should set this variable so
- that the mode name will appear in the mode line. The value does
- not have to be a string, but can use any of the data types valid
- in a mode-line construct (*note Mode Line Data::). To compute the
- string that will identify the mode name in the mode line, use
- `format-mode-line' (*note Emulating Mode Line::).
- -- Variable: mode-line-process
- This buffer-local variable contains the mode line information on
- process status in modes used for communicating with subprocesses.
- It is displayed immediately following the major mode name, with no
- intervening space. For example, its value in the `*shell*' buffer
- is `(":%s")', which allows the shell to display its status along
- with the major mode as: `(Shell:run)'. Normally this variable is
- `nil'.
- -- Variable: minor-mode-alist
- This variable holds an association list whose elements specify how
- the mode line should indicate that a minor mode is active. Each
- element of the `minor-mode-alist' should be a two-element list:
- (MINOR-MODE-VARIABLE MODE-LINE-STRING)
- More generally, MODE-LINE-STRING can be any mode line construct.
- It appears in the mode line when the value of MINOR-MODE-VARIABLE
- is non-`nil', and not otherwise. These strings should begin with
- spaces so that they don't run together. Conventionally, the
- MINOR-MODE-VARIABLE for a specific mode is set to a non-`nil'
- value when that minor mode is activated.
- `minor-mode-alist' itself is not buffer-local. Each variable
- mentioned in the alist should be buffer-local if its minor mode
- can be enabled separately in each buffer.
- -- Variable: global-mode-string
- This variable holds a mode line construct that, by default,
- appears in the mode line just after the `which-func-mode' minor
- mode if set, else after `mode-line-modes'. The command
- `display-time' sets `global-mode-string' to refer to the variable
- `display-time-string', which holds a string containing the time and
- load information.
- The `%M' construct substitutes the value of `global-mode-string',
- but that is obsolete, since the variable is included in the mode
- line from `mode-line-format'.
- Here is a simplified version of the default value of
- `mode-line-format'. The real default value also specifies addition of
- text properties.
- ("-"
- mode-line-mule-info
- mode-line-modified
- mode-line-frame-identification
- mode-line-buffer-identification
- " "
- mode-line-position
- (vc-mode vc-mode)
- " "
- mode-line-modes
- (which-func-mode ("" which-func-format "--"))
- (global-mode-string ("--" global-mode-string))
- "-%-")
- File: elisp, Node: %-Constructs, Next: Properties in Mode, Prev: Mode Line Variables, Up: Mode Line Format
- 23.4.5 `%'-Constructs in the Mode Line
- --------------------------------------
- Strings used as mode line constructs can use certain `%'-constructs to
- substitute various kinds of data. Here is a list of the defined
- `%'-constructs, and what they mean. In any construct except `%%', you
- can add a decimal integer after the `%' to specify a minimum field
- width. If the width is less, the field is padded with spaces to the
- right.
- `%b'
- The current buffer name, obtained with the `buffer-name' function.
- *Note Buffer Names::.
- `%c'
- The current column number of point.
- `%e'
- When Emacs is nearly out of memory for Lisp objects, a brief
- message saying so. Otherwise, this is empty.
- `%f'
- The visited file name, obtained with the `buffer-file-name'
- function. *Note Buffer File Name::.
- `%F'
- The title (only on a window system) or the name of the selected
- frame. *Note Basic Parameters::.
- `%i'
- The size of the accessible part of the current buffer; basically
- `(- (point-max) (point-min))'.
- `%I'
- Like `%i', but the size is printed in a more readable way by using
- `k' for 10^3, `M' for 10^6, `G' for 10^9, etc., to abbreviate.
- `%l'
- The current line number of point, counting within the accessible
- portion of the buffer.
- `%n'
- `Narrow' when narrowing is in effect; nothing otherwise (see
- `narrow-to-region' in *note Narrowing::).
- `%p'
- The percentage of the buffer text above the *top* of window, or
- `Top', `Bottom' or `All'. Note that the default mode line
- construct truncates this to three characters.
- `%P'
- The percentage of the buffer text that is above the *bottom* of
- the window (which includes the text visible in the window, as well
- as the text above the top), plus `Top' if the top of the buffer is
- visible on screen; or `Bottom' or `All'.
- `%s'
- The status of the subprocess belonging to the current buffer,
- obtained with `process-status'. *Note Process Information::.
- `%t'
- Whether the visited file is a text file or a binary file. This is
- a meaningful distinction only on certain operating systems (*note
- MS-DOS File Types::).
- `%z'
- The mnemonics of keyboard, terminal, and buffer coding systems.
- `%Z'
- Like `%z', but including the end-of-line format.
- `%*'
- `%' if the buffer is read only (see `buffer-read-only');
- `*' if the buffer is modified (see `buffer-modified-p');
- `-' otherwise. *Note Buffer Modification::.
- `%+'
- `*' if the buffer is modified (see `buffer-modified-p');
- `%' if the buffer is read only (see `buffer-read-only');
- `-' otherwise. This differs from `%*' only for a modified
- read-only buffer. *Note Buffer Modification::.
- `%&'
- `*' if the buffer is modified, and `-' otherwise.
- `%['
- An indication of the depth of recursive editing levels (not
- counting minibuffer levels): one `[' for each editing level.
- *Note Recursive Editing::.
- `%]'
- One `]' for each recursive editing level (not counting minibuffer
- levels).
- `%-'
- Dashes sufficient to fill the remainder of the mode line.
- `%%'
- The character `%'--this is how to include a literal `%' in a
- string in which `%'-constructs are allowed.
- The following two `%'-constructs are still supported, but they are
- obsolete, since you can get the same results with the variables
- `mode-name' and `global-mode-string'.
- `%m'
- The value of `mode-name'.
- `%M'
- The value of `global-mode-string'.
- File: elisp, Node: Properties in Mode, Next: Header Lines, Prev: %-Constructs, Up: Mode Line Format
- 23.4.6 Properties in the Mode Line
- ----------------------------------
- Certain text properties are meaningful in the mode line. The `face'
- property affects the appearance of text; the `help-echo' property
- associates help strings with the text, and `local-map' can make the
- text mouse-sensitive.
- There are four ways to specify text properties for text in the mode
- line:
- 1. Put a string with a text property directly into the mode line data
- structure.
- 2. Put a text property on a mode line %-construct such as `%12b'; then
- the expansion of the %-construct will have that same text property.
- 3. Use a `(:propertize ELT PROPS...)' construct to give ELT a text
- property specified by PROPS.
- 4. Use a list containing `:eval FORM' in the mode line data
- structure, and make FORM evaluate to a string that has a text
- property.
- You can use the `local-map' property to specify a keymap. This
- keymap only takes real effect for mouse clicks; binding character keys
- and function keys to it has no effect, since it is impossible to move
- point into the mode line.
- When the mode line refers to a variable which does not have a
- non-`nil' `risky-local-variable' property, any text properties given or
- specified within that variable's values are ignored. This is because
- such properties could otherwise specify functions to be called, and
- those functions could come from file local variables.
- File: elisp, Node: Header Lines, Next: Emulating Mode Line, Prev: Properties in Mode, Up: Mode Line Format
- 23.4.7 Window Header Lines
- --------------------------
- A window can have a "header line" at the top, just as it can have a
- mode line at the bottom. The header line feature works just like the
- mode line feature, except that it's controlled by `header-line-format':
- -- Variable: header-line-format
- This variable, local in every buffer, specifies how to display the
- header line, for windows displaying the buffer. The format of the
- value is the same as for `mode-line-format' (*note Mode Line
- Data::). It is normally `nil', so that ordinary buffers have no
- header line.
- A window that is just one line tall never displays a header line. A
- window that is two lines tall cannot display both a mode line and a
- header line at once; if it has a mode line, then it does not display a
- header line.
- File: elisp, Node: Emulating Mode Line, Prev: Header Lines, Up: Mode Line Format
- 23.4.8 Emulating Mode Line Formatting
- -------------------------------------
- You can use the function `format-mode-line' to compute the text that
- would appear in a mode line or header line based on a certain mode line
- construct.
- -- Function: format-mode-line format &optional face window buffer
- This function formats a line of text according to FORMAT as if it
- were generating the mode line for WINDOW, but it also returns the
- text as a string. The argument WINDOW defaults to the selected
- window. If BUFFER is non-`nil', all the information used is taken
- from BUFFER; by default, it comes from WINDOW's buffer.
- The value string normally has text properties that correspond to
- the faces, keymaps, etc., that the mode line would have. Any
- character for which no `face' property is specified by FORMAT gets
- a default value determined by FACE. If FACE is `t', that stands
- for either `mode-line' if WINDOW is selected, otherwise
- `mode-line-inactive'. If FACE is `nil' or omitted, that stands
- for the default face. If FACE is an integer, the value returned
- by this function will have no text properties.
- You can also specify other valid faces as the value of FACE. If
- specified, that face provides the `face' property for characters
- whose face is not specified by FORMAT.
- Note that using `mode-line', `mode-line-inactive', or
- `header-line' as FACE will actually redisplay the mode line or the
- header line, respectively, using the current definitions of the
- corresponding face, in addition to returning the formatted string.
- (Other faces do not cause redisplay.)
- For example, `(format-mode-line header-line-format)' returns the
- text that would appear in the selected window's header line (`""'
- if it has no header line). `(format-mode-line header-line-format
- 'header-line)' returns the same text, with each character carrying
- the face that it will have in the header line itself, and also
- redraws the header line.
- File: elisp, Node: Imenu, Next: Font Lock Mode, Prev: Mode Line Format, Up: Modes
- 23.5 Imenu
- ==========
- "Imenu" is a feature that lets users select a definition or section in
- the buffer, from a menu which lists all of them, to go directly to that
- location in the buffer. Imenu works by constructing a buffer index
- which lists the names and buffer positions of the definitions, or other
- named portions of the buffer; then the user can choose one of them and
- move point to it. Major modes can add a menu bar item to use Imenu
- using `imenu-add-to-menubar'.
- -- Command: imenu-add-to-menubar name
- This function defines a local menu bar item named NAME to run
- Imenu.
- The user-level commands for using Imenu are described in the Emacs
- Manual (*note Imenu: (emacs)Imenu.). This section explains how to
- customize Imenu's method of finding definitions or buffer portions for
- a particular major mode.
- The usual and simplest way is to set the variable
- `imenu-generic-expression':
- -- Variable: imenu-generic-expression
- This variable, if non-`nil', is a list that specifies regular
- expressions for finding definitions for Imenu. Simple elements of
- `imenu-generic-expression' look like this:
- (MENU-TITLE REGEXP INDEX)
- Here, if MENU-TITLE is non-`nil', it says that the matches for
- this element should go in a submenu of the buffer index;
- MENU-TITLE itself specifies the name for the submenu. If
- MENU-TITLE is `nil', the matches for this element go directly in
- the top level of the buffer index.
- The second item in the list, REGEXP, is a regular expression
- (*note Regular Expressions::); anything in the buffer that it
- matches is considered a definition, something to mention in the
- buffer index. The third item, INDEX, is a non-negative integer
- that indicates which subexpression in REGEXP matches the
- definition's name.
- An element can also look like this:
- (MENU-TITLE REGEXP INDEX FUNCTION ARGUMENTS...)
- Each match for this element creates an index item, and when the
- index item is selected by the user, it calls FUNCTION with
- arguments consisting of the item name, the buffer position, and
- ARGUMENTS.
- For Emacs Lisp mode, `imenu-generic-expression' could look like
- this:
- ((nil "^\\s-*(def\\(un\\|subst\\|macro\\|advice\\)\
- \\s-+\\([-A-Za-z0-9+]+\\)" 2)
- ("*Vars*" "^\\s-*(def\\(var\\|const\\)\
- \\s-+\\([-A-Za-z0-9+]+\\)" 2)
- ("*Types*"
- "^\\s-*\
- (def\\(type\\|struct\\|class\\|ine-condition\\)\
- \\s-+\\([-A-Za-z0-9+]+\\)" 2))
- Setting this variable makes it buffer-local in the current buffer.
- -- Variable: imenu-case-fold-search
- This variable controls whether matching against the regular
- expressions in the value of `imenu-generic-expression' is
- case-sensitive: `t', the default, means matching should ignore
- case.
- Setting this variable makes it buffer-local in the current buffer.
- -- Variable: imenu-syntax-alist
- This variable is an alist of syntax table modifiers to use while
- processing `imenu-generic-expression', to override the syntax table
- of the current buffer. Each element should have this form:
- (CHARACTERS . SYNTAX-DESCRIPTION)
- The CAR, CHARACTERS, can be either a character or a string. The
- element says to give that character or characters the syntax
- specified by SYNTAX-DESCRIPTION, which is passed to
- `modify-syntax-entry' (*note Syntax Table Functions::).
- This feature is typically used to give word syntax to characters
- which normally have symbol syntax, and thus to simplify
- `imenu-generic-expression' and speed up matching. For example,
- Fortran mode uses it this way:
- (setq imenu-syntax-alist '(("_$" . "w")))
- The `imenu-generic-expression' regular expressions can then use
- `\\sw+' instead of `\\(\\sw\\|\\s_\\)+'. Note that this technique
- may be inconvenient when the mode needs to limit the initial
- character of a name to a smaller set of characters than are
- allowed in the rest of a name.
- Setting this variable makes it buffer-local in the current buffer.
- Another way to customize Imenu for a major mode is to set the
- variables `imenu-prev-index-position-function' and
- `imenu-extract-index-name-function':
- -- Variable: imenu-prev-index-position-function
- If this variable is non-`nil', its value should be a function that
- finds the next "definition" to put in the buffer index, scanning
- backward in the buffer from point. It should return `nil' if it
- doesn't find another "definition" before point. Otherwise it
- should leave point at the place it finds a "definition" and return
- any non-`nil' value.
- Setting this variable makes it buffer-local in the current buffer.
- -- Variable: imenu-extract-index-name-function
- If this variable is non-`nil', its value should be a function to
- return the name for a definition, assuming point is in that
- definition as the `imenu-prev-index-position-function' function
- would leave it.
- Setting this variable makes it buffer-local in the current buffer.
- The last way to customize Imenu for a major mode is to set the
- variable `imenu-create-index-function':
- -- Variable: imenu-create-index-function
- This variable specifies the function to use for creating a buffer
- index. The function should take no arguments, and return an index
- alist for the current buffer. It is called within
- `save-excursion', so where it leaves point makes no difference.
- The index alist can have three types of elements. Simple elements
- look like this:
- (INDEX-NAME . INDEX-POSITION)
- Selecting a simple element has the effect of moving to position
- INDEX-POSITION in the buffer. Special elements look like this:
- (INDEX-NAME INDEX-POSITION FUNCTION ARGUMENTS...)
- Selecting a special element performs:
- (funcall FUNCTION
- INDEX-NAME INDEX-POSITION ARGUMENTS...)
- A nested sub-alist element looks like this:
- (MENU-TITLE SUB-ALIST)
- It creates the submenu MENU-TITLE specified by SUB-ALIST.
- The default value of `imenu-create-index-function' is
- `imenu-default-create-index-function'. This function calls the
- value of `imenu-prev-index-position-function' and the value of
- `imenu-extract-index-name-function' to produce the index alist.
- However, if either of these two variables is `nil', the default
- function uses `imenu-generic-expression' instead.
- Setting this variable makes it buffer-local in the current buffer.
- File: elisp, Node: Font Lock Mode, Next: Auto-Indentation, Prev: Imenu, Up: Modes
- 23.6 Font Lock Mode
- ===================
- "Font Lock mode" is a buffer-local minor mode that automatically
- attaches `face' properties to certain parts of the buffer based on
- their syntactic role. How it parses the buffer depends on the major
- mode; most major modes define syntactic criteria for which faces to use
- in which contexts. This section explains how to customize Font Lock for
- a particular major mode.
- Font Lock mode finds text to highlight in two ways: through
- syntactic parsing based on the syntax table, and through searching
- (usually for regular expressions). Syntactic fontification happens
- first; it finds comments and string constants and highlights them.
- Search-based fontification happens second.
- * Menu:
- * Font Lock Basics:: Overview of customizing Font Lock.
- * Search-based Fontification:: Fontification based on regexps.
- * Customizing Keywords:: Customizing search-based fontification.
- * Other Font Lock Variables:: Additional customization facilities.
- * Levels of Font Lock:: Each mode can define alternative levels
- so that the user can select more or less.
- * Precalculated Fontification:: How Lisp programs that produce the buffer
- contents can also specify how to fontify it.
- * Faces for Font Lock:: Special faces specifically for Font Lock.
- * Syntactic Font Lock:: Fontification based on syntax tables.
- * Multiline Font Lock:: How to coerce Font Lock into properly
- highlighting multiline constructs.
- File: elisp, Node: Font Lock Basics, Next: Search-based Fontification, Up: Font Lock Mode
- 23.6.1 Font Lock Basics
- -----------------------
- There are several variables that control how Font Lock mode highlights
- text. But major modes should not set any of these variables directly.
- Instead, they should set `font-lock-defaults' as a buffer-local
- variable. The value assigned to this variable is used, if and when Font
- Lock mode is enabled, to set all the other variables.
- -- Variable: font-lock-defaults
- This variable is set by major modes to specify how to fontify text
- in that mode. It automatically becomes buffer-local when set. If
- its value is `nil', Font Lock mode does no highlighting, and you
- can use the `Faces' menu (under `Edit' and then `Text Properties'
- in the menu bar) to assign faces explicitly to text in the buffer.
- If non-`nil', the value should look like this:
- (KEYWORDS [KEYWORDS-ONLY [CASE-FOLD
- [SYNTAX-ALIST [SYNTAX-BEGIN OTHER-VARS...]]]])
- The first element, KEYWORDS, indirectly specifies the value of
- `font-lock-keywords' which directs search-based fontification. It
- can be a symbol, a variable or a function whose value is the list
- to use for `font-lock-keywords'. It can also be a list of several
- such symbols, one for each possible level of fontification. The
- first symbol specifies the `mode default' level of fontification,
- the next symbol level 1 fontification, the next level 2, and so
- on. The `mode default' level is normally the same as level 1. It
- is used when `font-lock-maximum-decoration' has a `nil' value.
- *Note Levels of Font Lock::.
- The second element, KEYWORDS-ONLY, specifies the value of the
- variable `font-lock-keywords-only'. If this is omitted or `nil',
- syntactic fontification (of strings and comments) is also
- performed. If this is non-`nil', syntactic fontification is not
- performed. *Note Syntactic Font Lock::.
- The third element, CASE-FOLD, specifies the value of
- `font-lock-keywords-case-fold-search'. If it is non-`nil', Font
- Lock mode ignores case during search-based fontification.
- If the fourth element, SYNTAX-ALIST, is non-`nil', it should be a
- list of cons cells of the form `(CHAR-OR-STRING . STRING)'. These
- are used to set up a syntax table for syntactic fontification; the
- resulting syntax table is stored in `font-lock-syntax-table'. If
- SYNTAX-ALIST is omitted or `nil', syntactic fontification uses the
- syntax table returned by the `syntax-table' function. *Note
- Syntax Table Functions::.
- The fifth element, SYNTAX-BEGIN, specifies the value of
- `font-lock-beginning-of-syntax-function'. We recommend setting
- this variable to `nil' and using `syntax-begin-function' instead.
- All the remaining elements (if any) are collectively called
- OTHER-VARS. Each of these elements should have the form
- `(VARIABLE . VALUE)'--which means, make VARIABLE buffer-local and
- then set it to VALUE. You can use these OTHER-VARS to set other
- variables that affect fontification, aside from those you can
- control with the first five elements. *Note Other Font Lock
- Variables::.
- If your mode fontifies text explicitly by adding `font-lock-face'
- properties, it can specify `(nil t)' for `font-lock-defaults' to turn
- off all automatic fontification. However, this is not required; it is
- possible to fontify some things using `font-lock-face' properties and
- set up automatic fontification for other parts of the text.
- File: elisp, Node: Search-based Fontification, Next: Customizing Keywords, Prev: Font Lock Basics, Up: Font Lock Mode
- 23.6.2 Search-based Fontification
- ---------------------------------
- The variable which directly controls search-based fontification is
- `font-lock-keywords', which is typically specified via the KEYWORDS
- element in `font-lock-defaults'.
- -- Variable: font-lock-keywords
- The value of this variable is a list of the keywords to highlight.
- Lisp programs should not set this variable directly. Normally,
- the value is automatically set by Font Lock mode, using the
- KEYWORDS element in `font-lock-defaults'. The value can also be
- altered using the functions `font-lock-add-keywords' and
- `font-lock-remove-keywords' (*note Customizing Keywords::).
- Each element of `font-lock-keywords' specifies how to find certain
- cases of text, and how to highlight those cases. Font Lock mode
- processes the elements of `font-lock-keywords' one by one, and for each
- element, it finds and handles all matches. Ordinarily, once part of
- the text has been fontified already, this cannot be overridden by a
- subsequent match in the same text; but you can specify different
- behavior using the OVERRIDE element of a SUBEXP-HIGHLIGHTER.
- Each element of `font-lock-keywords' should have one of these forms:
- `REGEXP'
- Highlight all matches for REGEXP using `font-lock-keyword-face'.
- For example,
- ;; Highlight occurrences of the word `foo'
- ;; using `font-lock-keyword-face'.
- "\\<foo\\>"
- Be careful when composing these regular expressions; a poorly
- written pattern can dramatically slow things down! The function
- `regexp-opt' (*note Regexp Functions::) is useful for calculating
- optimal regular expressions to match several keywords.
- `FUNCTION'
- Find text by calling FUNCTION, and highlight the matches it finds
- using `font-lock-keyword-face'.
- When FUNCTION is called, it receives one argument, the limit of
- the search; it should begin searching at point, and not search
- beyond the limit. It should return non-`nil' if it succeeds, and
- set the match data to describe the match that was found.
- Returning `nil' indicates failure of the search.
- Fontification will call FUNCTION repeatedly with the same limit,
- and with point where the previous invocation left it, until
- FUNCTION fails. On failure, FUNCTION need not reset point in any
- particular way.
- `(MATCHER . SUBEXP)'
- In this kind of element, MATCHER is either a regular expression or
- a function, as described above. The CDR, SUBEXP, specifies which
- subexpression of MATCHER should be highlighted (instead of the
- entire text that MATCHER matched).
- ;; Highlight the `bar' in each occurrence of `fubar',
- ;; using `font-lock-keyword-face'.
- ("fu\\(bar\\)" . 1)
- If you use `regexp-opt' to produce the regular expression MATCHER,
- you can use `regexp-opt-depth' (*note Regexp Functions::) to
- calculate the value for SUBEXP.
- `(MATCHER . FACESPEC)'
- In this kind of element, FACESPEC is an expression whose value
- specifies the face to use for highlighting. In the simplest case,
- FACESPEC is a Lisp variable (a symbol) whose value is a face name.
- ;; Highlight occurrences of `fubar',
- ;; using the face which is the value of `fubar-face'.
- ("fubar" . fubar-face)
- However, FACESPEC can also evaluate to a list of this form:
- (face FACE PROP1 VAL1 PROP2 VAL2...)
- to specify the face FACE and various additional text properties to
- put on the text that matches. If you do this, be sure to add the
- other text property names that you set in this way to the value of
- `font-lock-extra-managed-props' so that the properties will also
- be cleared out when they are no longer appropriate. Alternatively,
- you can set the variable `font-lock-unfontify-region-function' to
- a function that clears these properties. *Note Other Font Lock
- Variables::.
- `(MATCHER . SUBEXP-HIGHLIGHTER)'
- In this kind of element, SUBEXP-HIGHLIGHTER is a list which
- specifies how to highlight matches found by MATCHER. It has the
- form:
- (SUBEXP FACESPEC [OVERRIDE [LAXMATCH]])
- The CAR, SUBEXP, is an integer specifying which subexpression of
- the match to fontify (0 means the entire matching text). The
- second subelement, FACESPEC, is an expression whose value
- specifies the face, as described above.
- The last two values in SUBEXP-HIGHLIGHTER, OVERRIDE and LAXMATCH,
- are optional flags. If OVERRIDE is `t', this element can override
- existing fontification made by previous elements of
- `font-lock-keywords'. If it is `keep', then each character is
- fontified if it has not been fontified already by some other
- element. If it is `prepend', the face specified by FACESPEC is
- added to the beginning of the `font-lock-face' property. If it is
- `append', the face is added to the end of the `font-lock-face'
- property.
- If LAXMATCH is non-`nil', it means there should be no error if
- there is no subexpression numbered SUBEXP in MATCHER. Obviously,
- fontification of the subexpression numbered SUBEXP will not occur.
- However, fontification of other subexpressions (and other regexps)
- will continue. If LAXMATCH is `nil', and the specified
- subexpression is missing, then an error is signaled which
- terminates search-based fontification.
- Here are some examples of elements of this kind, and what they do:
- ;; Highlight occurrences of either `foo' or `bar', using
- ;; `foo-bar-face', even if they have already been highlighted.
- ;; `foo-bar-face' should be a variable whose value is a face.
- ("foo\\|bar" 0 foo-bar-face t)
- ;; Highlight the first subexpression within each occurrence
- ;; that the function `fubar-match' finds,
- ;; using the face which is the value of `fubar-face'.
- (fubar-match 1 fubar-face)
- `(MATCHER . ANCHORED-HIGHLIGHTER)'
- In this kind of element, ANCHORED-HIGHLIGHTER specifies how to
- highlight text that follows a match found by MATCHER. So a match
- found by MATCHER acts as the anchor for further searches specified
- by ANCHORED-HIGHLIGHTER. ANCHORED-HIGHLIGHTER is a list of the
- following form:
- (ANCHORED-MATCHER PRE-FORM POST-FORM
- SUBEXP-HIGHLIGHTERS...)
- Here, ANCHORED-MATCHER, like MATCHER, is either a regular
- expression or a function. After a match of MATCHER is found,
- point is at the end of the match. Now, Font Lock evaluates the
- form PRE-FORM. Then it searches for matches of ANCHORED-MATCHER
- and uses SUBEXP-HIGHLIGHTERS to highlight these. A
- SUBEXP-HIGHLIGHTER is as described above. Finally, Font Lock
- evaluates POST-FORM.
- The forms PRE-FORM and POST-FORM can be used to initialize before,
- and cleanup after, ANCHORED-MATCHER is used. Typically, PRE-FORM
- is used to move point to some position relative to the match of
- MATCHER, before starting with ANCHORED-MATCHER. POST-FORM might
- be used to move back, before resuming with MATCHER.
- After Font Lock evaluates PRE-FORM, it does not search for
- ANCHORED-MATCHER beyond the end of the line. However, if PRE-FORM
- returns a buffer position that is greater than the position of
- point after PRE-FORM is evaluated, then the position returned by
- PRE-FORM is used as the limit of the search instead. It is
- generally a bad idea to return a position greater than the end of
- the line; in other words, the ANCHORED-MATCHER search should not
- span lines.
- For example,
- ;; Highlight occurrences of the word `item' following
- ;; an occurrence of the word `anchor' (on the same line)
- ;; in the value of `item-face'.
- ("\\<anchor\\>" "\\<item\\>" nil nil (0 item-face))
- Here, PRE-FORM and POST-FORM are `nil'. Therefore searching for
- `item' starts at the end of the match of `anchor', and searching
- for subsequent instances of `anchor' resumes from where searching
- for `item' concluded.
- `(MATCHER HIGHLIGHTERS...)'
- This sort of element specifies several HIGHLIGHTER lists for a
- single MATCHER. A HIGHLIGHTER list can be of the type
- SUBEXP-HIGHLIGHTER or ANCHORED-HIGHLIGHTER as described above.
- For example,
- ;; Highlight occurrences of the word `anchor' in the value
- ;; of `anchor-face', and subsequent occurrences of the word
- ;; `item' (on the same line) in the value of `item-face'.
- ("\\<anchor\\>" (0 anchor-face)
- ("\\<item\\>" nil nil (0 item-face)))
- `(eval . FORM)'
- Here FORM is an expression to be evaluated the first time this
- value of `font-lock-keywords' is used in a buffer. Its value
- should have one of the forms described in this table.
- *Warning:* Do not design an element of `font-lock-keywords' to match
- text which spans lines; this does not work reliably. For details, see
- *Note Multiline Font Lock::.
- You can use CASE-FOLD in `font-lock-defaults' to specify the value
- of `font-lock-keywords-case-fold-search' which says whether
- search-based fontification should be case-insensitive.
- -- Variable: font-lock-keywords-case-fold-search
- Non-`nil' means that regular expression matching for the sake of
- `font-lock-keywords' should be case-insensitive.
- File: elisp, Node: Customizing Keywords, Next: Other Font Lock Variables, Prev: Search-based Fontification, Up: Font Lock Mode
- 23.6.3 Customizing Search-Based Fontification
- ---------------------------------------------
- You can use `font-lock-add-keywords' to add additional search-based
- fontification rules to a major mode, and `font-lock-remove-keywords' to
- remove rules.
- -- Function: font-lock-add-keywords mode keywords &optional how
- This function adds highlighting KEYWORDS, for the current buffer
- or for major mode MODE. The argument KEYWORDS should be a list
- with the same format as the variable `font-lock-keywords'.
- If MODE is a symbol which is a major mode command name, such as
- `c-mode', the effect is that enabling Font Lock mode in MODE will
- add KEYWORDS to `font-lock-keywords'. Calling with a non-`nil'
- value of MODE is correct only in your `~/.emacs' file.
- If MODE is `nil', this function adds KEYWORDS to
- `font-lock-keywords' in the current buffer. This way of calling
- `font-lock-add-keywords' is usually used in mode hook functions.
- By default, KEYWORDS are added at the beginning of
- `font-lock-keywords'. If the optional argument HOW is `set', they
- are used to replace the value of `font-lock-keywords'. If HOW is
- any other non-`nil' value, they are added at the end of
- `font-lock-keywords'.
- Some modes provide specialized support you can use in additional
- highlighting patterns. See the variables
- `c-font-lock-extra-types', `c++-font-lock-extra-types', and
- `java-font-lock-extra-types', for example.
- *Warning:* Major mode commands must not call
- `font-lock-add-keywords' under any circumstances, either directly
- or indirectly, except through their mode hooks. (Doing so would
- lead to incorrect behavior for some minor modes.) They should set
- up their rules for search-based fontification by setting
- `font-lock-keywords'.
- -- Function: font-lock-remove-keywords mode keywords
- This function removes KEYWORDS from `font-lock-keywords' for the
- current buffer or for major mode MODE. As in
- `font-lock-add-keywords', MODE should be a major mode command name
- or `nil'. All the caveats and requirements for
- `font-lock-add-keywords' apply here too.
- For example, the following code adds two fontification patterns for C
- mode: one to fontify the word `FIXME', even in comments, and another to
- fontify the words `and', `or' and `not' as keywords.
- (font-lock-add-keywords 'c-mode
- '(("\\<\\(FIXME\\):" 1 font-lock-warning-face prepend)
- ("\\<\\(and\\|or\\|not\\)\\>" . font-lock-keyword-face)))
- This example affects only C mode proper. To add the same patterns to C
- mode _and_ all modes derived from it, do this instead:
- (add-hook 'c-mode-hook
- (lambda ()
- (font-lock-add-keywords nil
- '(("\\<\\(FIXME\\):" 1 font-lock-warning-face prepend)
- ("\\<\\(and\\|or\\|not\\)\\>" .
- font-lock-keyword-face)))))
- File: elisp, Node: Other Font Lock Variables, Next: Levels of Font Lock, Prev: Customizing Keywords, Up: Font Lock Mode
- 23.6.4 Other Font Lock Variables
- --------------------------------
- This section describes additional variables that a major mode can set
- by means of OTHER-VARS in `font-lock-defaults' (*note Font Lock
- Basics::).
- -- Variable: font-lock-mark-block-function
- If this variable is non-`nil', it should be a function that is
- called with no arguments, to choose an enclosing range of text for
- refontification for the command `M-o M-o'
- (`font-lock-fontify-block').
- The function should report its choice by placing the region around
- it. A good choice is a range of text large enough to give proper
- results, but not too large so that refontification becomes slow.
- Typical values are `mark-defun' for programming modes or
- `mark-paragraph' for textual modes.
- -- Variable: font-lock-extra-managed-props
- This variable specifies additional properties (other than
- `font-lock-face') that are being managed by Font Lock mode. It is
- used by `font-lock-default-unfontify-region', which normally only
- manages the `font-lock-face' property. If you want Font Lock to
- manage other properties as well, you must specify them in a
- FACESPEC in `font-lock-keywords' as well as add them to this list.
- *Note Search-based Fontification::.
- -- Variable: font-lock-fontify-buffer-function
- Function to use for fontifying the buffer. The default value is
- `font-lock-default-fontify-buffer'.
- -- Variable: font-lock-unfontify-buffer-function
- Function to use for unfontifying the buffer. This is used when
- turning off Font Lock mode. The default value is
- `font-lock-default-unfontify-buffer'.
- -- Variable: font-lock-fontify-region-function
- Function to use for fontifying a region. It should take two
- arguments, the beginning and end of the region, and an optional
- third argument VERBOSE. If VERBOSE is non-`nil', the function
- should print status messages. The default value is
- `font-lock-default-fontify-region'.
- -- Variable: font-lock-unfontify-region-function
- Function to use for unfontifying a region. It should take two
- arguments, the beginning and end of the region. The default value
- is `font-lock-default-unfontify-region'.
- -- Function: jit-lock-register function &optional contextual
- This function tells Font Lock mode to run the Lisp function
- FUNCTION any time it has to fontify or refontify part of the
- current buffer. It calls FUNCTION before calling the default
- fontification functions, and gives it two arguments, START and
- END, which specify the region to be fontified or refontified.
- The optional argument CONTEXTUAL, if non-`nil', forces Font Lock
- mode to always refontify a syntactically relevant part of the
- buffer, and not just the modified lines. This argument can
- usually be omitted.
- -- Function: jit-lock-unregister function
- If FUNCTION was previously registered as a fontification function
- using `jit-lock-register', this function unregisters it.
- File: elisp, Node: Levels of Font Lock, Next: Precalculated Fontification, Prev: Other Font Lock Variables, Up: Font Lock Mode
- 23.6.5 Levels of Font Lock
- --------------------------
- Some major modes offer three different levels of fontification. You
- can define multiple levels by using a list of symbols for KEYWORDS in
- `font-lock-defaults'. Each symbol specifies one level of
- fontification; it is up to the user to choose one of these levels,
- normally by setting `font-lock-maximum-decoration' (*note Font Lock:
- (emacs)Font Lock.). The chosen level's symbol value is used to
- initialize `font-lock-keywords'.
- Here are the conventions for how to define the levels of
- fontification:
- * Level 1: highlight function declarations, file directives (such as
- include or import directives), strings and comments. The idea is
- speed, so only the most important and top-level components are
- fontified.
- * Level 2: in addition to level 1, highlight all language keywords,
- including type names that act like keywords, as well as named
- constant values. The idea is that all keywords (either syntactic
- or semantic) should be fontified appropriately.
- * Level 3: in addition to level 2, highlight the symbols being
- defined in function and variable declarations, and all builtin
- function names, wherever they appear.
- File: elisp, Node: Precalculated Fontification, Next: Faces for Font Lock, Prev: Levels of Font Lock, Up: Font Lock Mode
- 23.6.6 Precalculated Fontification
- ----------------------------------
- Some major modes such as `list-buffers' and `occur' construct the
- buffer text programmatically. The easiest way for them to support Font
- Lock mode is to specify the faces of text when they insert the text in
- the buffer.
- The way to do this is to specify the faces in the text with the
- special text property `font-lock-face' (*note Special Properties::).
- When Font Lock mode is enabled, this property controls the display,
- just like the `face' property. When Font Lock mode is disabled,
- `font-lock-face' has no effect on the display.
- It is ok for a mode to use `font-lock-face' for some text and also
- use the normal Font Lock machinery. But if the mode does not use the
- normal Font Lock machinery, it should not set the variable
- `font-lock-defaults'.
- File: elisp, Node: Faces for Font Lock, Next: Syntactic Font Lock, Prev: Precalculated Fontification, Up: Font Lock Mode
- 23.6.7 Faces for Font Lock
- --------------------------
- Font Lock mode can highlight using any face, but Emacs defines several
- faces specifically for Font Lock to use to highlight text. These "Font
- Lock faces" are listed below. They can also be used by major modes for
- syntactic highlighting outside of Font Lock mode (*note Major Mode
- Conventions::).
- Each of these symbols is both a face name, and a variable whose
- default value is the symbol itself. Thus, the default value of
- `font-lock-comment-face' is `font-lock-comment-face'.
- The faces are listed with descriptions of their typical usage, and in
- order of greater to lesser "prominence". If a mode's syntactic
- categories do not fit well with the usage descriptions, the faces can be
- assigned using the ordering as a guide.
- `font-lock-warning-face'
- for a construct that is peculiar, or that greatly changes the
- meaning of other text, like `;;;###autoload' in Emacs Lisp and
- `#error' in C.
- `font-lock-function-name-face'
- for the name of a function being defined or declared.
- `font-lock-variable-name-face'
- for the name of a variable being defined or declared.
- `font-lock-keyword-face'
- for a keyword with special syntactic significance, like `for' and
- `if' in C.
- `font-lock-comment-face'
- for comments.
- `font-lock-comment-delimiter-face'
- for comments delimiters, like `/*' and `*/' in C. On most
- terminals, this inherits from `font-lock-comment-face'.
- `font-lock-type-face'
- for the names of user-defined data types.
- `font-lock-constant-face'
- for the names of constants, like `NULL' in C.
- `font-lock-builtin-face'
- for the names of built-in functions.
- `font-lock-preprocessor-face'
- for preprocessor commands. This inherits, by default, from
- `font-lock-builtin-face'.
- `font-lock-string-face'
- for string constants.
- `font-lock-doc-face'
- for documentation strings in the code. This inherits, by default,
- from `font-lock-string-face'.
- `font-lock-negation-char-face'
- for easily-overlooked negation characters.
- File: elisp, Node: Syntactic Font Lock, Next: Multiline Font Lock, Prev: Faces for Font Lock, Up: Font Lock Mode
- 23.6.8 Syntactic Font Lock
- --------------------------
- Syntactic fontification uses a syntax table (*note Syntax Tables::) to
- find and highlight syntactically relevant text. If enabled, it runs
- prior to search-based fontification. The variable
- `font-lock-syntactic-face-function', documented below, determines which
- syntactic constructs to highlight. There are several variables that
- affect syntactic fontification; you should set them by means of
- `font-lock-defaults' (*note Font Lock Basics::).
- Whenever Font Lock mode performs syntactic fontification on a stretch
- of text, it first calls the function specified by
- `syntax-propertize-function'. Major modes can use this to apply
- `syntax-table' text properties to override the buffer's syntax table in
- special cases. *Note Syntax Properties::.
- -- Variable: font-lock-keywords-only
- If the value of this variable is non-`nil', Font Lock does not do
- syntactic fontification, only search-based fontification based on
- `font-lock-keywords'. It is normally set by Font Lock mode based
- on the KEYWORDS-ONLY element in `font-lock-defaults'.
- -- Variable: font-lock-syntax-table
- This variable holds the syntax table to use for fontification of
- comments and strings. It is normally set by Font Lock mode based
- on the SYNTAX-ALIST element in `font-lock-defaults'. If this value
- is `nil', syntactic fontification uses the buffer's syntax table
- (the value returned by the function `syntax-table'; *note Syntax
- Table Functions::).
- -- Variable: font-lock-beginning-of-syntax-function
- If this variable is non-`nil', it should be a function to move
- point back to a position that is syntactically at "top level" and
- outside of strings or comments. The value is normally set through
- an OTHER-VARS element in `font-lock-defaults'. If it is `nil',
- Font Lock uses `syntax-begin-function' to move back outside of any
- comment, string, or sexp (*note Position Parse::).
- This variable is semi-obsolete; we usually recommend setting
- `syntax-begin-function' instead. One of its uses is to tune the
- behavior of syntactic fontification, e.g. to ensure that different
- kinds of strings or comments are highlighted differently.
- The specified function is called with no arguments. It should
- leave point at the beginning of any enclosing syntactic block.
- Typical values are `beginning-of-line' (used when the start of the
- line is known to be outside a syntactic block), or
- `beginning-of-defun' for programming modes, or
- `backward-paragraph' for textual modes.
- -- Variable: font-lock-syntactic-face-function
- If this variable is non-`nil', it should be a function to determine
- which face to use for a given syntactic element (a string or a
- comment). The value is normally set through an OTHER-VARS element
- in `font-lock-defaults'.
- The function is called with one argument, the parse state at point
- returned by `parse-partial-sexp', and should return a face. The
- default value returns `font-lock-comment-face' for comments and
- `font-lock-string-face' for strings (*note Faces for Font Lock::).
- File: elisp, Node: Multiline Font Lock, Prev: Syntactic Font Lock, Up: Font Lock Mode
- 23.6.9 Multiline Font Lock Constructs
- -------------------------------------
- Normally, elements of `font-lock-keywords' should not match across
- multiple lines; that doesn't work reliably, because Font Lock usually
- scans just part of the buffer, and it can miss a multi-line construct
- that crosses the line boundary where the scan starts. (The scan
- normally starts at the beginning of a line.)
- Making elements that match multiline constructs work properly has
- two aspects: correct _identification_ and correct _rehighlighting_.
- The first means that Font Lock finds all multiline constructs. The
- second means that Font Lock will correctly rehighlight all the relevant
- text when a multiline construct is changed--for example, if some of the
- text that was previously part of a multiline construct ceases to be
- part of it. The two aspects are closely related, and often getting one
- of them to work will appear to make the other also work. However, for
- reliable results you must attend explicitly to both aspects.
- There are three ways to ensure correct identification of multiline
- constructs:
- * Add a function to `font-lock-extend-region-functions' that does
- the _identification_ and extends the scan so that the scanned text
- never starts or ends in the middle of a multiline construct.
- * Use the `font-lock-fontify-region-function' hook similarly to
- extend the scan so that the scanned text never starts or ends in
- the middle of a multiline construct.
- * Somehow identify the multiline construct right when it gets
- inserted into the buffer (or at any point after that but before
- font-lock tries to highlight it), and mark it with a
- `font-lock-multiline' which will instruct font-lock not to start
- or end the scan in the middle of the construct.
- There are three ways to do rehighlighting of multiline constructs:
- * Place a `font-lock-multiline' property on the construct. This
- will rehighlight the whole construct if any part of it is changed.
- In some cases you can do this automatically by setting the
- `font-lock-multiline' variable, which see.
- * Make sure `jit-lock-contextually' is set and rely on it doing its
- job. This will only rehighlight the part of the construct that
- follows the actual change, and will do it after a short delay.
- This only works if the highlighting of the various parts of your
- multiline construct never depends on text in subsequent lines.
- Since `jit-lock-contextually' is activated by default, this can be
- an attractive solution.
- * Place a `jit-lock-defer-multiline' property on the construct.
- This works only if `jit-lock-contextually' is used, and with the
- same delay before rehighlighting, but like `font-lock-multiline',
- it also handles the case where highlighting depends on subsequent
- lines.
- * Menu:
- * Font Lock Multiline:: Marking multiline chunks with a text property.
- * Region to Refontify:: Controlling which region gets refontified
- after a buffer change.
- File: elisp, Node: Font Lock Multiline, Next: Region to Refontify, Up: Multiline Font Lock
- 23.6.9.1 Font Lock Multiline
- ............................
- One way to ensure reliable rehighlighting of multiline Font Lock
- constructs is to put on them the text property `font-lock-multiline'.
- It should be present and non-`nil' for text that is part of a multiline
- construct.
- When Font Lock is about to highlight a range of text, it first
- extends the boundaries of the range as necessary so that they do not
- fall within text marked with the `font-lock-multiline' property. Then
- it removes any `font-lock-multiline' properties from the range, and
- highlights it. The highlighting specification (mostly
- `font-lock-keywords') must reinstall this property each time, whenever
- it is appropriate.
- *Warning:* don't use the `font-lock-multiline' property on large
- ranges of text, because that will make rehighlighting slow.
- -- Variable: font-lock-multiline
- If the `font-lock-multiline' variable is set to `t', Font Lock
- will try to add the `font-lock-multiline' property automatically
- on multiline constructs. This is not a universal solution,
- however, since it slows down Font Lock somewhat. It can miss some
- multiline constructs, or make the property larger or smaller than
- necessary.
- For elements whose MATCHER is a function, the function should
- ensure that submatch 0 covers the whole relevant multiline
- construct, even if only a small subpart will be highlighted. It
- is often just as easy to add the `font-lock-multiline' property by
- hand.
- The `font-lock-multiline' property is meant to ensure proper
- refontification; it does not automatically identify new multiline
- constructs. Identifying the requires that Font Lock mode operate on
- large enough chunks at a time. This will happen by accident on many
- cases, which may give the impression that multiline constructs magically
- work. If you set the `font-lock-multiline' variable non-`nil', this
- impression will be even stronger, since the highlighting of those
- constructs which are found will be properly updated from then on. But
- that does not work reliably.
- To find multiline constructs reliably, you must either manually place
- the `font-lock-multiline' property on the text before Font Lock mode
- looks at it, or use `font-lock-fontify-region-function'.
- File: elisp, Node: Region to Refontify, Prev: Font Lock Multiline, Up: Multiline Font Lock
- 23.6.9.2 Region to Fontify after a Buffer Change
- ................................................
- When a buffer is changed, the region that Font Lock refontifies is by
- default the smallest sequence of whole lines that spans the change.
- While this works well most of the time, sometimes it doesn't--for
- example, when a change alters the syntactic meaning of text on an
- earlier line.
- You can enlarge (or even reduce) the region to refontify by setting
- the following variable:
- -- Variable: font-lock-extend-after-change-region-function
- This buffer-local variable is either `nil' or a function for Font
- Lock mode to call to determine the region to scan and fontify.
- The function is given three parameters, the standard BEG, END, and
- OLD-LEN from `after-change-functions' (*note Change Hooks::). It
- should return either a cons of the beginning and end buffer
- positions (in that order) of the region to fontify, or `nil'
- (which means choose the region in the standard way). This
- function needs to preserve point, the match-data, and the current
- restriction. The region it returns may start or end in the middle
- of a line.
- Since this function is called after every buffer change, it should
- be reasonably fast.
- File: elisp, Node: Auto-Indentation, Next: Desktop Save Mode, Prev: Font Lock Mode, Up: Modes
- 23.7 Automatic Indentation of code
- ==================================
- For programming languages, an important feature of a major mode is to
- provide automatic indentation. This is controlled in Emacs by
- `indent-line-function' (*note Mode-Specific Indent::). Writing a good
- indentation function can be difficult and to a large extent it is still
- a black art.
- Many major mode authors will start by writing a simple indentation
- function that works for simple cases, for example by comparing with the
- indentation of the previous text line. For most programming languages
- that are not really line-based, this tends to scale very poorly:
- improving such a function to let it handle more diverse situations tends
- to become more and more difficult, resulting in the end with a large,
- complex, unmaintainable indentation function which nobody dares to
- touch.
- A good indentation function will usually need to actually parse the
- text, according to the syntax of the language. Luckily, it is not
- necessary to parse the text in as much detail as would be needed for a
- compiler, but on the other hand, the parser embedded in the indentation
- code will want to be somewhat friendly to syntactically incorrect code.
- Good maintainable indentation functions usually fall into two
- categories: either parsing forward from some "safe" starting point
- until the position of interest, or parsing backward from the position
- of interest. Neither of the two is a clearly better choice than the
- other: parsing backward is often more difficult than parsing forward
- because programming languages are designed to be parsed forward, but
- for the purpose of indentation it has the advantage of not needing to
- guess a "safe" starting point, and it generally enjoys the property
- that only a minimum of text will be analyzed to decide the indentation
- of a line, so indentation will tend to be unaffected by syntax errors in
- some earlier unrelated piece of code. Parsing forward on the other hand
- is usually easier and has the advantage of making it possible to
- reindent efficiently a whole region at a time, with a single parse.
- Rather than write your own indentation function from scratch, it is
- often preferable to try and reuse some existing ones or to rely on a
- generic indentation engine. There are sadly few such engines. The
- CC-mode indentation code (used with C, C++, Java, Awk and a few other
- such modes) has been made more generic over the years, so if your
- language seems somewhat similar to one of those languages, you might
- try to use that engine. Another one is SMIE which takes an approach in
- the spirit of Lisp sexps and adapts it to non-Lisp languages.
- * Menu:
- * SMIE:: A simple minded indentation engine.
- File: elisp, Node: SMIE, Up: Auto-Indentation
- 23.7.1 Simple Minded Indentation Engine
- ---------------------------------------
- SMIE is a package that provides a generic navigation and indentation
- engine. Based on a very simple parser using an "operator precedence
- grammar", it lets major modes extend the sexp-based navigation of Lisp
- to non-Lisp languages as well as provide a simple to use but reliable
- auto-indentation.
- Operator precedence grammar is a very primitive technology for
- parsing compared to some of the more common techniques used in
- compilers. It has the following characteristics: its parsing power is
- very limited, and it is largely unable to detect syntax errors, but it
- has the advantage of being algorithmically efficient and able to parse
- forward just as well as backward. In practice that means that SMIE can
- use it for indentation based on backward parsing, that it can provide
- both `forward-sexp' and `backward-sexp' functionality, and that it will
- naturally work on syntactically incorrect code without any extra
- effort. The downside is that it also means that most programming
- languages cannot be parsed correctly using SMIE, at least not without
- resorting to some special tricks (*note SMIE Tricks::).
- * Menu:
- * SMIE setup:: SMIE setup and features.
- * Operator Precedence Grammars:: A very simple parsing technique.
- * SMIE Grammar:: Defining the grammar of a language.
- * SMIE Lexer:: Defining tokens.
- * SMIE Tricks:: Working around the parser's limitations.
- * SMIE Indentation:: Specifying indentation rules.
- * SMIE Indentation Helpers:: Helper functions for indentation rules.
- * SMIE Indentation Example:: Sample indentation rules.
- File: elisp, Node: SMIE setup, Next: Operator Precedence Grammars, Up: SMIE
- 23.7.1.1 SMIE Setup and Features
- ................................
- SMIE is meant to be a one-stop shop for structural navigation and
- various other features which rely on the syntactic structure of code, in
- particular automatic indentation. The main entry point is `smie-setup'
- which is a function typically called while setting up a major mode.
- -- Function: smie-setup grammar rules-function &rest keywords
- Setup SMIE navigation and indentation. GRAMMAR is a grammar table
- generated by `smie-prec2->grammar'. RULES-FUNCTION is a set of
- indentation rules for use on `smie-rules-function'. KEYWORDS are
- additional arguments, which can include the following keywords:
- * `:forward-token' FUN: Specify the forward lexer to use.
- * `:backward-token' FUN: Specify the backward lexer to use.
- Calling this function is sufficient to make commands such as
- `forward-sexp', `backward-sexp', and `transpose-sexps' be able to
- properly handle structural elements other than just the paired
- parentheses already handled by syntax tables. For example, if the
- provided grammar is precise enough, `transpose-sexps' can correctly
- transpose the two arguments of a `+' operator, taking into account the
- precedence rules of the language.
- Calling `smie-setup' is also sufficient to make TAB indentation work
- in the expected way, extends `blink-matching-paren' to apply to
- elements like `begin...end', and provides some commands that you can
- bind in the major mode keymap.
- -- Command: smie-close-block
- This command closes the most recently opened (and not yet closed)
- block.
- -- Command: smie-down-list &optional arg
- This command is like `down-list' but it also pays attention to
- nesting of tokens other than parentheses, such as `begin...end'.
- File: elisp, Node: Operator Precedence Grammars, Next: SMIE Grammar, Prev: SMIE setup, Up: SMIE
- 23.7.1.2 Operator Precedence Grammars
- .....................................
- SMIE's precedence grammars simply give to each token a pair of
- precedences: the left-precedence and the right-precedence. We say `T1
- < T2' if the right-precedence of token `T1' is less than the
- left-precedence of token `T2'. A good way to read this `<' is as a
- kind of parenthesis: if we find `... T1 something T2 ...' then that
- should be parsed as `... T1 (something T2 ...' rather than as `... T1
- something) T2 ...'. The latter interpretation would be the case if we
- had `T1 > T2'. If we have `T1 = T2', it means that token T2 follows
- token T1 in the same syntactic construction, so typically we have
- `"begin" = "end"'. Such pairs of precedences are sufficient to express
- left-associativity or right-associativity of infix operators, nesting
- of tokens like parentheses and many other cases.
- -- Function: smie-prec2->grammar table
- This function takes a _prec2_ grammar TABLE and returns an alist
- suitable for use in `smie-setup'. The _prec2_ TABLE is itself
- meant to be built by one of the functions below.
- -- Function: smie-merge-prec2s &rest tables
- This function takes several _prec2_ TABLES and merges them into a
- new _prec2_ table.
- -- Function: smie-precs->prec2 precs
- This function builds a _prec2_ table from a table of precedences
- PRECS. PRECS should be a list, sorted by precedence (for example
- `"+"' will come before `"*"'), of elements of the form `(ASSOC OP
- ...)', where each OP is a token that acts as an operator; ASSOC is
- their associativity, which can be either `left', `right', `assoc',
- or `nonassoc'. All operators in a given element share the same
- precedence level and associativity.
- -- Function: smie-bnf->prec2 bnf &rest resolvers
- This function lets you specify the grammar using a BNF notation.
- It accepts a BNF description of the grammar along with a set of
- conflict resolution rules RESOLVERS, and returns a _prec2_ table.
- BNF is a list of nonterminal definitions of the form `(NONTERM
- RHS1 RHS2 ...)' where each RHS is a (non-empty) list of terminals
- (aka tokens) or non-terminals.
- Not all grammars are accepted:
- * An RHS cannot be an empty list (an empty list is never needed,
- since SMIE allows all non-terminals to match the empty string
- anyway).
- * An RHS cannot have 2 consecutive non-terminals: each pair of
- non-terminals needs to be separated by a terminal (aka token).
- This is a fundamental limitation of operator precedence
- grammars.
- Additionally, conflicts can occur:
- * The returned _prec2_ table holds constraints between pairs of
- tokens, and for any given pair only one constraint can be
- present: T1 < T2, T1 = T2, or T1 > T2.
- * A token can be an `opener' (something similar to an
- open-paren), a `closer' (like a close-paren), or `neither' of
- the two (e.g. an infix operator, or an inner token like
- `"else"').
- Precedence conflicts can be resolved via RESOLVERS, which is a
- list of _precs_ tables (see `smie-precs->prec2'): for each
- precedence conflict, if those `precs' tables specify a particular
- constraint, then the conflict is resolved by using this constraint
- instead, else a conflict is reported and one of the conflicting
- constraints is picked arbitrarily and the others are simply
- ignored.
- File: elisp, Node: SMIE Grammar, Next: SMIE Lexer, Prev: Operator Precedence Grammars, Up: SMIE
- 23.7.1.3 Defining the Grammar of a Language
- ...........................................
- The usual way to define the SMIE grammar of a language is by defining a
- new global variable that holds the precedence table by giving a set of
- BNF rules. For example, the grammar definition for a small Pascal-like
- language could look like:
- (require 'smie)
- (defvar sample-smie-grammar
- (smie-prec2->grammar
- (smie-bnf->prec2
- '((id)
- (inst ("begin" insts "end")
- ("if" exp "then" inst "else" inst)
- (id ":=" exp)
- (exp))
- (insts (insts ";" insts) (inst))
- (exp (exp "+" exp)
- (exp "*" exp)
- ("(" exps ")"))
- (exps (exps "," exps) (exp)))
- '((assoc ";"))
- '((assoc ","))
- '((assoc "+") (assoc "*")))))
- A few things to note:
- * The above grammar does not explicitly mention the syntax of
- function calls: SMIE will automatically allow any sequence of
- sexps, such as identifiers, balanced parentheses, or `begin ...
- end' blocks to appear anywhere anyway.
- * The grammar category `id' has no right hand side: this does not
- mean that it can match only the empty string, since as mentioned
- any sequence of sexps can appear anywhere anyway.
- * Because non terminals cannot appear consecutively in the BNF
- grammar, it is difficult to correctly handle tokens that act as
- terminators, so the above grammar treats `";"' as a statement
- _separator_ instead, which SMIE can handle very well.
- * Separators used in sequences (such as `","' and `";"' above) are
- best defined with BNF rules such as `(foo (foo "separator" foo)
- ...)' which generate precedence conflicts which are then resolved
- by giving them an explicit `(assoc "separator")'.
- * The `("(" exps ")")' rule was not needed to pair up parens, since
- SMIE will pair up any characters that are marked as having paren
- syntax in the syntax table. What this rule does instead (together
- with the definition of `exps') is to make it clear that `","'
- should not appear outside of parentheses.
- * Rather than have a single _precs_ table to resolve conflicts, it is
- preferable to have several tables, so as to let the BNF part of the
- grammar specify relative precedences where possible.
- * Unless there is a very good reason to prefer `left' or `right', it
- is usually preferable to mark operators as associative, using
- `assoc'. For that reason `"+"' and `"*"' are defined above as
- `assoc', although the language defines them formally as left
- associative.
- File: elisp, Node: SMIE Lexer, Next: SMIE Tricks, Prev: SMIE Grammar, Up: SMIE
- 23.7.1.4 Defining Tokens
- ........................
- SMIE comes with a predefined lexical analyzer which uses syntax tables
- in the following way: any sequence of characters that have word or
- symbol syntax is considered a token, and so is any sequence of
- characters that have punctuation syntax. This default lexer is often a
- good starting point but is rarely actually correct for any given
- language. For example, it will consider `"2,+3"' to be composed of 3
- tokens: `"2"', `",+"', and `"3"'.
- To describe the lexing rules of your language to SMIE, you need 2
- functions, one to fetch the next token, and another to fetch the
- previous token. Those functions will usually first skip whitespace and
- comments and then look at the next chunk of text to see if it is a
- special token. If so it should skip the token and return a description
- of this token. Usually this is simply the string extracted from the
- buffer, but it can be anything you want. For example:
- (defvar sample-keywords-regexp
- (regexp-opt '("+" "*" "," ";" ">" ">=" "<" "<=" ":=" "=")))
- (defun sample-smie-forward-token ()
- (forward-comment (point-max))
- (cond
- ((looking-at sample-keywords-regexp)
- (goto-char (match-end 0))
- (match-string-no-properties 0))
- (t (buffer-substring-no-properties
- (point)
- (progn (skip-syntax-forward "w_")
- (point))))))
- (defun sample-smie-backward-token ()
- (forward-comment (- (point)))
- (cond
- ((looking-back sample-keywords-regexp (- (point) 2) t)
- (goto-char (match-beginning 0))
- (match-string-no-properties 0))
- (t (buffer-substring-no-properties
- (point)
- (progn (skip-syntax-backward "w_")
- (point))))))
- Notice how those lexers return the empty string when in front of
- parentheses. This is because SMIE automatically takes care of the
- parentheses defined in the syntax table. More specifically if the lexer
- returns nil or an empty string, SMIE tries to handle the corresponding
- text as a sexp according to syntax tables.
- File: elisp, Node: SMIE Tricks, Next: SMIE Indentation, Prev: SMIE Lexer, Up: SMIE
- 23.7.1.5 Living With a Weak Parser
- ..................................
- The parsing technique used by SMIE does not allow tokens to behave
- differently in different contexts. For most programming languages, this
- manifests itself by precedence conflicts when converting the BNF
- grammar.
- Sometimes, those conflicts can be worked around by expressing the
- grammar slightly differently. For example, for Modula-2 it might seem
- natural to have a BNF grammar that looks like this:
- ...
- (inst ("IF" exp "THEN" insts "ELSE" insts "END")
- ("CASE" exp "OF" cases "END")
- ...)
- (cases (cases "|" cases)
- (caselabel ":" insts)
- ("ELSE" insts))
- ...
- But this will create conflicts for `"ELSE"': on the one hand, the IF
- rule implies (among many other things) that `"ELSE" = "END"'; but on
- the other hand, since `"ELSE"' appears within `cases', which appears
- left of `"END"', we also have `"ELSE" > "END"'. We can solve the
- conflict either by using:
- ...
- (inst ("IF" exp "THEN" insts "ELSE" insts "END")
- ("CASE" exp "OF" cases "END")
- ("CASE" exp "OF" cases "ELSE" insts "END")
- ...)
- (cases (cases "|" cases) (caselabel ":" insts))
- ...
- or
- ...
- (inst ("IF" exp "THEN" else "END")
- ("CASE" exp "OF" cases "END")
- ...)
- (else (insts "ELSE" insts))
- (cases (cases "|" cases) (caselabel ":" insts) (else))
- ...
- Reworking the grammar to try and solve conflicts has its downsides,
- tho, because SMIE assumes that the grammar reflects the logical
- structure of the code, so it is preferable to keep the BNF closer to
- the intended abstract syntax tree.
- Other times, after careful consideration you may conclude that those
- conflicts are not serious and simply resolve them via the RESOLVERS
- argument of `smie-bnf->prec2'. Usually this is because the grammar is
- simply ambiguous: the conflict does not affect the set of programs
- described by the grammar, but only the way those programs are parsed.
- This is typically the case for separators and associative infix
- operators, where you want to add a resolver like `'((assoc "|"))'.
- Another case where this can happen is for the classic _dangling else_
- problem, where you will use `'((assoc "else" "then"))'. It can also
- happen for cases where the conflict is real and cannot really be
- resolved, but it is unlikely to pose a problem in practice.
- Finally, in many cases some conflicts will remain despite all
- efforts to restructure the grammar. Do not despair: while the parser
- cannot be made more clever, you can make the lexer as smart as you
- want. So, the solution is then to look at the tokens involved in the
- conflict and to split one of those tokens into 2 (or more) different
- tokens. E.g. if the grammar needs to distinguish between two
- incompatible uses of the token `"begin"', make the lexer return
- different tokens (say `"begin-fun"' and `"begin-plain"') depending on
- which kind of `"begin"' it finds. This pushes the work of
- distinguishing the different cases to the lexer, which will thus have
- to look at the surrounding text to find ad-hoc clues.
- File: elisp, Node: SMIE Indentation, Next: SMIE Indentation Helpers, Prev: SMIE Tricks, Up: SMIE
- 23.7.1.6 Specifying Indentation Rules
- .....................................
- Based on the provided grammar, SMIE will be able to provide automatic
- indentation without any extra effort. But in practice, this default
- indentation style will probably not be good enough. You will want to
- tweak it in many different cases.
- SMIE indentation is based on the idea that indentation rules should
- be as local as possible. To this end, it relies on the idea of
- _virtual_ indentation, which is the indentation that a particular
- program point would have if it were at the beginning of a line. Of
- course, if that program point is indeed at the beginning of a line, its
- virtual indentation is its current indentation. But if not, then SMIE
- uses the indentation algorithm to compute the virtual indentation of
- that point. Now in practice, the virtual indentation of a program
- point does not have to be identical to the indentation it would have if
- we inserted a newline before it. To see how this works, the SMIE rule
- for indentation after a `{' in C does not care whether the `{' is
- standing on a line of its own or is at the end of the preceding line.
- Instead, these different cases are handled in the indentation rule that
- decides how to indent before a `{'.
- Another important concept is the notion of _parent_: The _parent_ of
- a token, is the head token of the nearest enclosing syntactic
- construct. For example, the parent of an `else' is the `if' to which
- it belongs, and the parent of an `if', in turn, is the lead token of
- the surrounding construct. The command `backward-sexp' jumps from a
- token to its parent, but there are some caveats: for _openers_ (tokens
- which start a construct, like `if'), you need to start with point
- before the token, while for others you need to start with point after
- the token. `backward-sexp' stops with point before the parent token if
- that is the _opener_ of the token of interest, and otherwise it stops
- with point after the parent token.
- SMIE indentation rules are specified using a function that takes two
- arguments METHOD and ARG where the meaning of ARG and the expected
- return value depend on METHOD.
- METHOD can be:
- * `:after', in which case ARG is a token and the function should
- return the OFFSET to use for indentation after ARG.
- * `:before', in which case ARG is a token and the function should
- return the OFFSET to use to indent ARG itself.
- * `:elem', in which case the function should return either the offset
- to use to indent function arguments (if ARG is the symbol `arg')
- or the basic indentation step (if ARG is the symbol `basic').
- * `:list-intro', in which case ARG is a token and the function
- should return non-`nil' if the token is followed by a list of
- expressions (not separated by any token) rather than an expression.
- When ARG is a token, the function is called with point just before
- that token. A return value of nil always means to fallback on the
- default behavior, so the function should return nil for arguments it
- does not expect.
- OFFSET can be:
- * `nil': use the default indentation rule.
- * `(column . COLUMN)': indent to column COLUMN.
- * NUMBER: offset by NUMBER, relative to a base token which is the
- current token for `:after' and its parent for `:before'.
- File: elisp, Node: SMIE Indentation Helpers, Next: SMIE Indentation Example, Prev: SMIE Indentation, Up: SMIE
- 23.7.1.7 Helper Functions for Indentation Rules
- ...............................................
- SMIE provides various functions designed specifically for use in the
- indentation rules function (several of those functions break if used in
- another context). These functions all start with the prefix
- `smie-rule-'.
- -- Function: smie-rule-bolp
- Return non-`nil' if the current token is the first on the line.
- -- Function: smie-rule-hanging-p
- Return non-`nil' if the current token is _hanging_. A token is
- _hanging_ if it is the last token on the line and if it is
- preceded by other tokens: a lone token on a line is not hanging.
- -- Function: smie-rule-next-p &rest tokens
- Return non-`nil' if the next token is among TOKENS.
- -- Function: smie-rule-prev-p &rest tokens
- Return non-`nil' if the previous token is among TOKENS.
- -- Function: smie-rule-parent-p &rest parents
- Return non-`nil' if the current token's parent is among PARENTS.
- -- Function: smie-rule-sibling-p
- Return non-`nil' if the current token's parent is actually a
- sibling. This is the case for example when the parent of a `","'
- is just the previous `","'.
- -- Function: smie-rule-parent &optional offset
- Return the proper offset to align the current token with the
- parent. If non-`nil', OFFSET should be an integer giving an
- additional offset to apply.
- -- Function: smie-rule-separator method
- Indent current token as a _separator_.
- By _separator_, we mean here a token whose sole purpose is to
- separate various elements within some enclosing syntactic
- construct, and which does not have any semantic significance in
- itself (i.e. it would typically not exist as a node in an abstract
- syntax tree).
- Such a token is expected to have an associative syntax and be
- closely tied to its syntactic parent. Typical examples are `","'
- in lists of arguments (enclosed inside parentheses), or `";"' in
- sequences of instructions (enclosed in a `{...}' or `begin...end'
- block).
- METHOD should be the method name that was passed to
- `smie-rules-function'.
- File: elisp, Node: SMIE Indentation Example, Prev: SMIE Indentation Helpers, Up: SMIE
- 23.7.1.8 Sample Indentation Rules
- .................................
- Here is an example of an indentation function:
- (defun sample-smie-rules (kind token)
- (pcase (cons kind token)
- (`(:elem . basic) sample-indent-basic)
- (`(,_ . ",") (smie-rule-separator kind))
- (`(:after . ":=") sample-indent-basic)
- (`(:before . ,(or `"begin" `"(" `"{")))
- (if (smie-rule-hanging-p) (smie-rule-parent)))
- (`(:before . "if")
- (and (not (smie-rule-bolp)) (smie-rule-prev-p "else")
- (smie-rule-parent)))))
- A few things to note:
- * The first case indicates the basic indentation increment to use.
- If `sample-indent-basic' is nil, then SMIE uses the global setting
- `smie-indent-basic'. The major mode could have set
- `smie-indent-basic' buffer-locally instead, but that is
- discouraged.
- * The rule for the token `","' make SMIE try to be more clever when
- the comma separator is placed at the beginning of lines. It tries
- to outdent the separator so as to align the code after the comma;
- for example:
- x = longfunctionname (
- arg1
- , arg2
- );
- * The rule for indentation after `":="' exists because otherwise
- SMIE would treat `":="' as an infix operator and would align the
- right argument with the left one.
- * The rule for indentation before `"begin"' is an example of the use
- of virtual indentation: This rule is used only when `"begin"' is
- hanging, which can happen only when `"begin"' is not at the
- beginning of a line. So this is not used when indenting `"begin"'
- itself but only when indenting something relative to this
- `"begin"'. Concretely, this rule changes the indentation from:
- if x > 0 then begin
- dosomething(x);
- end
- to
- if x > 0 then begin
- dosomething(x);
- end
- * The rule for indentation before `"if"' is similar to the one for
- `"begin"', but where the purpose is to treat `"else if"' as a
- single unit, so as to align a sequence of tests rather than indent
- each test further to the right. This function does this only in
- the case where the `"if"' is not placed on a separate line, hence
- the `smie-rule-bolp' test.
- If we know that the `"else"' is always aligned with its `"if"' and
- is always at the beginning of a line, we can use a more efficient
- rule:
- ((equal token "if")
- (and (not (smie-rule-bolp))
- (smie-rule-prev-p "else")
- (save-excursion
- (sample-smie-backward-token)
- (cons 'column (current-column)))))
- The advantage of this formulation is that it reuses the
- indentation of the previous `"else"', rather than going all the
- way back to the first `"if"' of the sequence.
- File: elisp, Node: Desktop Save Mode, Prev: Auto-Indentation, Up: Modes
- 23.8 Desktop Save Mode
- ======================
- "Desktop Save Mode" is a feature to save the state of Emacs from one
- session to another. The user-level commands for using Desktop Save
- Mode are described in the GNU Emacs Manual (*note Saving Emacs
- Sessions: (emacs)Saving Emacs Sessions.). Modes whose buffers visit a
- file, don't have to do anything to use this feature.
- For buffers not visiting a file to have their state saved, the major
- mode must bind the buffer local variable `desktop-save-buffer' to a
- non-`nil' value.
- -- Variable: desktop-save-buffer
- If this buffer-local variable is non-`nil', the buffer will have
- its state saved in the desktop file at desktop save. If the value
- is a function, it is called at desktop save with argument
- DESKTOP-DIRNAME, and its value is saved in the desktop file along
- with the state of the buffer for which it was called. When file
- names are returned as part of the auxiliary information, they
- should be formatted using the call
- (desktop-file-name FILE-NAME DESKTOP-DIRNAME)
- For buffers not visiting a file to be restored, the major mode must
- define a function to do the job, and that function must be listed in
- the alist `desktop-buffer-mode-handlers'.
- -- Variable: desktop-buffer-mode-handlers
- Alist with elements
- (MAJOR-MODE . RESTORE-BUFFER-FUNCTION)
- The function RESTORE-BUFFER-FUNCTION will be called with argument
- list
- (BUFFER-FILE-NAME BUFFER-NAME DESKTOP-BUFFER-MISC)
- and it should return the restored buffer. Here
- DESKTOP-BUFFER-MISC is the value returned by the function
- optionally bound to `desktop-save-buffer'.
- File: elisp, Node: Documentation, Next: Files, Prev: Modes, Up: Top
- 24 Documentation
- ****************
- GNU Emacs has convenient built-in help facilities, most of which derive
- their information from documentation strings associated with functions
- and variables. This chapter describes how to access documentation
- strings in Lisp programs. *Note Documentation Tips::, for how to write
- good documentation strings.
- Note that the documentation strings for Emacs are not the same thing
- as the Emacs manual. Manuals have their own source files, written in
- the Texinfo language; documentation strings are specified in the
- definitions of the functions and variables they apply to. A collection
- of documentation strings is not sufficient as a manual because a good
- manual is not organized in that fashion; it is organized in terms of
- topics of discussion.
- For commands to display documentation strings, see *note Help:
- (emacs)Help.
- * Menu:
- * Documentation Basics:: Where doc strings are defined and stored.
- * Accessing Documentation:: How Lisp programs can access doc strings.
- * Keys in Documentation:: Substituting current key bindings.
- * Describing Characters:: Making printable descriptions of
- non-printing characters and key sequences.
- * Help Functions:: Subroutines used by Emacs help facilities.
- File: elisp, Node: Documentation Basics, Next: Accessing Documentation, Up: Documentation
- 24.1 Documentation Basics
- =========================
- A documentation string is written using the Lisp syntax for strings,
- with double-quote characters surrounding the text of the string. This
- is because it really is a Lisp string object. The string serves as
- documentation when it is written in the proper place in the definition
- of a function or variable. In a function definition, the documentation
- string follows the argument list. In a variable definition, the
- documentation string follows the initial value of the variable.
- When you write a documentation string, make the first line a
- complete sentence (or two complete sentences) that briefly describes
- what the function or variable does. Some commands, such as `apropos',
- show only the first line of a multi-line documentation string. Also,
- you should not indent the second line of a documentation string, if it
- has one, because that looks odd when you use `C-h f'
- (`describe-function') or `C-h v' (`describe-variable') to view the
- documentation string. There are many other conventions for
- documentation strings; see *note Documentation Tips::.
- Documentation strings can contain several special substrings, which
- stand for key bindings to be looked up in the current keymaps when the
- documentation is displayed. This allows documentation strings to refer
- to the keys for related commands and be accurate even when a user
- rearranges the key bindings. (*Note Keys in Documentation::.)
- Emacs Lisp mode fills documentation strings to the width specified
- by `emacs-lisp-docstring-fill-column'.
- Exactly where a documentation string is stored depends on how its
- function or variable was defined or loaded into memory:
- * When you define a function (*note Lambda Expressions::, and *note
- Function Documentation::), the documentation string is stored in
- the function definition itself. You can also put function
- documentation in the `function-documentation' property of a
- function name. That is useful for function definitions which can't
- hold a documentation string, such as keyboard macros.
- * When you define a variable with a `defvar' or related form (*note
- Defining Variables::), the documentation is stored in the
- variable's `variable-documentation' property.
- * To save memory, the documentation for preloaded functions and
- variables (including primitive functions and autoloaded functions)
- is not kept in memory, but in the file `emacs/etc/DOC-VERSION',
- where VERSION is the Emacs version number (*note Version Info::).
- * When a function or variable is loaded from a byte-compiled file
- during the Emacs session, its documentation string is not loaded
- into memory. Instead, Emacs looks it up in the byte-compiled file
- as needed. *Note Docs and Compilation::.
- Regardless of where the documentation string is stored, you can
- retrieve it using the `documentation' or `documentation-property'
- function, described in the next section.
- File: elisp, Node: Accessing Documentation, Next: Keys in Documentation, Prev: Documentation Basics, Up: Documentation
- 24.2 Access to Documentation Strings
- ====================================
- -- Function: documentation-property symbol property &optional verbatim
- This function returns the documentation string recorded in
- SYMBOL's property list under property PROPERTY. It is most often
- used to look up the documentation strings of variables, for which
- PROPERTY is `variable-documentation'. However, it can also be
- used to look up other kinds of documentation, such as for
- customization groups (but for function documentation, use the
- `documentation' command, below).
- If the value recorded in the property list refers to a
- documentation string stored in a `DOC-VERSION' file or a
- byte-compiled file, it looks up that string and returns it. If
- the property value isn't `nil', isn't a string, and doesn't refer
- to text in a file, then it is evaluated as a Lisp expression to
- obtain a string.
- The last thing this function does is pass the string through
- `substitute-command-keys' to substitute actual key bindings (*note
- Keys in Documentation::). However, it skips this step if VERBATIM
- is non-`nil'.
- (documentation-property 'command-line-processed
- 'variable-documentation)
- => "Non-nil once command line has been processed"
- (symbol-plist 'command-line-processed)
- => (variable-documentation 188902)
- (documentation-property 'emacs 'group-documentation)
- => "Customization of the One True Editor."
- -- Function: documentation function &optional verbatim
- This function returns the documentation string of FUNCTION. It
- handles macros, named keyboard macros, and special forms, as well
- as ordinary functions.
- If FUNCTION is a symbol, this function first looks for the
- `function-documentation' property of that symbol; if that has a
- non-`nil' value, the documentation comes from that value (if the
- value is not a string, it is evaluated). If FUNCTION is not a
- symbol, or if it has no `function-documentation' property, then
- `documentation' extracts the documentation string from the actual
- function definition, reading it from a file if called for.
- Finally, unless VERBATIM is non-`nil', it calls
- `substitute-command-keys' so as to return a value containing the
- actual (current) key bindings.
- The function `documentation' signals a `void-function' error if
- FUNCTION has no function definition. However, it is OK if the
- function definition has no documentation string. In that case,
- `documentation' returns `nil'.
- -- Function: face-documentation face
- This function returns the documentation string of FACE as a face.
- Here is an example of using the two functions, `documentation' and
- `documentation-property', to display the documentation strings for
- several symbols in a `*Help*' buffer.
- (defun describe-symbols (pattern)
- "Describe the Emacs Lisp symbols matching PATTERN.
- All symbols that have PATTERN in their name are described
- in the `*Help*' buffer."
- (interactive "sDescribe symbols matching: ")
- (let ((describe-func
- (function
- (lambda (s)
- ;; Print description of symbol.
- (if (fboundp s) ; It is a function.
- (princ
- (format "%s\t%s\n%s\n\n" s
- (if (commandp s)
- (let ((keys (where-is-internal s)))
- (if keys
- (concat
- "Keys: "
- (mapconcat 'key-description
- keys " "))
- "Keys: none"))
- "Function")
- (or (documentation s)
- "not documented"))))
- (if (boundp s) ; It is a variable.
- (princ
- (format "%s\t%s\n%s\n\n" s
- (if (user-variable-p s)
- "Option " "Variable")
- (or (documentation-property
- s 'variable-documentation)
- "not documented")))))))
- sym-list)
- ;; Build a list of symbols that match pattern.
- (mapatoms (function
- (lambda (sym)
- (if (string-match pattern (symbol-name sym))
- (setq sym-list (cons sym sym-list))))))
- ;; Display the data.
- (help-setup-xref (list 'describe-symbols pattern) (interactive-p))
- (with-help-window (help-buffer)
- (mapcar describe-func (sort sym-list 'string<)))))
- The `describe-symbols' function works like `apropos', but provides
- more information.
- (describe-symbols "goal")
- ---------- Buffer: *Help* ----------
- goal-column Option
- Semipermanent goal column for vertical motion, as set by ...
- set-goal-column Keys: C-x C-n
- Set the current horizontal position as a goal for C-n and C-p.
- Those commands will move to this position in the line moved to
- rather than trying to keep the same horizontal position.
- With a non-nil argument, clears out the goal column
- so that C-n and C-p resume vertical motion.
- The goal column is stored in the variable `goal-column'.
- temporary-goal-column Variable
- Current goal column for vertical motion.
- It is the column where point was
- at the start of current run of vertical motion commands.
- When the `track-eol' feature is doing its job, the value is 9999.
- ---------- Buffer: *Help* ----------
- -- Function: Snarf-documentation filename
- This function is used when building Emacs, just before the runnable
- Emacs is dumped. It finds the positions of the documentation
- strings stored in the file FILENAME, and records those positions
- into memory in the function definitions and variable property
- lists. *Note Building Emacs::.
- Emacs reads the file FILENAME from the `emacs/etc' directory.
- When the dumped Emacs is later executed, the same file will be
- looked for in the directory `doc-directory'. Usually FILENAME is
- `"DOC-VERSION"'.
- -- Variable: doc-directory
- This variable holds the name of the directory which should contain
- the file `"DOC-VERSION"' that contains documentation strings for
- built-in and preloaded functions and variables.
- In most cases, this is the same as `data-directory'. They may be
- different when you run Emacs from the directory where you built it,
- without actually installing it. *Note Definition of
- data-directory::.
- File: elisp, Node: Keys in Documentation, Next: Describing Characters, Prev: Accessing Documentation, Up: Documentation
- 24.3 Substituting Key Bindings in Documentation
- ===============================================
- When documentation strings refer to key sequences, they should use the
- current, actual key bindings. They can do so using certain special text
- sequences described below. Accessing documentation strings in the usual
- way substitutes current key binding information for these special
- sequences. This works by calling `substitute-command-keys'. You can
- also call that function yourself.
- Here is a list of the special sequences and what they mean:
- `\[COMMAND]'
- stands for a key sequence that will invoke COMMAND, or `M-x
- COMMAND' if COMMAND has no key bindings.
- `\{MAPVAR}'
- stands for a summary of the keymap which is the value of the
- variable MAPVAR. The summary is made using `describe-bindings'.
- `\<MAPVAR>'
- stands for no text itself. It is used only for a side effect: it
- specifies MAPVAR's value as the keymap for any following
- `\[COMMAND]' sequences in this documentation string.
- `\='
- quotes the following character and is discarded; thus, `\=\[' puts
- `\[' into the output, and `\=\=' puts `\=' into the output.
- *Please note:* Each `\' must be doubled when written in a string in
- Emacs Lisp.
- -- Function: substitute-command-keys string
- This function scans STRING for the above special sequences and
- replaces them by what they stand for, returning the result as a
- string. This permits display of documentation that refers
- accurately to the user's own customized key bindings.
- If a command has multiple bindings, this function normally uses the
- first one it finds. You can specify one particular key binding by
- assigning an `:advertised-binding' symbol property to the command,
- like this:
- (put 'undo :advertised-binding [?\C-/])
- The `:advertised-binding' property also affects the binding shown
- in menu items (*note Menu Bar::). The property is ignored if it
- specifies a key binding that the command does not actually have.
- Here are examples of the special sequences:
- (substitute-command-keys
- "To abort recursive edit, type: \\[abort-recursive-edit]")
- => "To abort recursive edit, type: C-]"
- (substitute-command-keys
- "The keys that are defined for the minibuffer here are:
- \\{minibuffer-local-must-match-map}")
- => "The keys that are defined for the minibuffer here are:
- ? minibuffer-completion-help
- SPC minibuffer-complete-word
- TAB minibuffer-complete
- C-j minibuffer-complete-and-exit
- RET minibuffer-complete-and-exit
- C-g abort-recursive-edit
- "
- (substitute-command-keys
- "To abort a recursive edit from the minibuffer, type\
- \\<minibuffer-local-must-match-map>\\[abort-recursive-edit].")
- => "To abort a recursive edit from the minibuffer, type C-g."
- There are other special conventions for the text in documentation
- strings--for instance, you can refer to functions, variables, and
- sections of this manual. *Note Documentation Tips::, for details.
- File: elisp, Node: Describing Characters, Next: Help Functions, Prev: Keys in Documentation, Up: Documentation
- 24.4 Describing Characters for Help Messages
- ============================================
- These functions convert events, key sequences, or characters to textual
- descriptions. These descriptions are useful for including arbitrary
- text characters or key sequences in messages, because they convert
- non-printing and whitespace characters to sequences of printing
- characters. The description of a non-whitespace printing character is
- the character itself.
- -- Function: key-description sequence &optional prefix
- This function returns a string containing the Emacs standard
- notation for the input events in SEQUENCE. If PREFIX is
- non-`nil', it is a sequence of input events leading up to SEQUENCE
- and is included in the return value. Both arguments may be
- strings, vectors or lists. *Note Input Events::, for more
- information about valid events.
- (key-description [?\M-3 delete])
- => "M-3 <delete>"
- (key-description [delete] "\M-3")
- => "M-3 <delete>"
- See also the examples for `single-key-description', below.
- -- Function: single-key-description event &optional no-angles
- This function returns a string describing EVENT in the standard
- Emacs notation for keyboard input. A normal printing character
- appears as itself, but a control character turns into a string
- starting with `C-', a meta character turns into a string starting
- with `M-', and space, tab, etc. appear as `SPC', `TAB', etc. A
- function key symbol appears inside angle brackets `<...>'. An
- event that is a list appears as the name of the symbol in the CAR
- of the list, inside angle brackets.
- If the optional argument NO-ANGLES is non-`nil', the angle
- brackets around function keys and event symbols are omitted; this
- is for compatibility with old versions of Emacs which didn't use
- the brackets.
- (single-key-description ?\C-x)
- => "C-x"
- (key-description "\C-x \M-y \n \t \r \f123")
- => "C-x SPC M-y SPC C-j SPC TAB SPC RET SPC C-l 1 2 3"
- (single-key-description 'delete)
- => "<delete>"
- (single-key-description 'C-mouse-1)
- => "<C-mouse-1>"
- (single-key-description 'C-mouse-1 t)
- => "C-mouse-1"
- -- Function: text-char-description character
- This function returns a string describing CHARACTER in the
- standard Emacs notation for characters that appear in text--like
- `single-key-description', except that control characters are
- represented with a leading caret (which is how control characters
- in Emacs buffers are usually displayed). Another difference is
- that `text-char-description' recognizes the 2**7 bit as the Meta
- character, whereas `single-key-description' uses the 2**27 bit for
- Meta.
- (text-char-description ?\C-c)
- => "^C"
- (text-char-description ?\M-m)
- => "\xed"
- (text-char-description ?\C-\M-m)
- => "\x8d"
- (text-char-description (+ 128 ?m))
- => "M-m"
- (text-char-description (+ 128 ?\C-m))
- => "M-^M"
- -- Command: read-kbd-macro string &optional need-vector
- This function is used mainly for operating on keyboard macros, but
- it can also be used as a rough inverse for `key-description'. You
- call it with a string containing key descriptions, separated by
- spaces; it returns a string or vector containing the corresponding
- events. (This may or may not be a single valid key sequence,
- depending on what events you use; *note Key Sequences::.) If
- NEED-VECTOR is non-`nil', the return value is always a vector.
- File: elisp, Node: Help Functions, Prev: Describing Characters, Up: Documentation
- 24.5 Help Functions
- ===================
- Emacs provides a variety of on-line help functions, all accessible to
- the user as subcommands of the prefix `C-h'. For more information
- about them, see *note Help: (emacs)Help. Here we describe some
- program-level interfaces to the same information.
- -- Command: apropos pattern &optional do-all
- This function finds all "meaningful" symbols whose names contain a
- match for the apropos pattern PATTERN. An apropos pattern is
- either a word to match, a space-separated list of words of which at
- least two must match, or a regular expression (if any special
- regular expression characters occur). A symbol is "meaningful" if
- it has a definition as a function, variable, or face, or has
- properties.
- The function returns a list of elements that look like this:
- (SYMBOL SCORE FUNCTION-DOC VARIABLE-DOC
- PLIST-DOC WIDGET-DOC FACE-DOC GROUP-DOC)
- Here, SCORE is an integer measure of how important the symbol
- seems to be as a match. Each of the remaining elements is a
- documentation string, or `nil', for SYMBOL as a function,
- variable, etc.
- It also displays the symbols in a buffer named `*Apropos*', each
- with a one-line description taken from the beginning of its
- documentation string.
- If DO-ALL is non-`nil', or if the user option `apropos-do-all' is
- non-`nil', then `apropos' also shows key bindings for the
- functions that are found; it also shows _all_ interned symbols,
- not just meaningful ones (and it lists them in the return value as
- well).
- -- Variable: help-map
- The value of this variable is a local keymap for characters
- following the Help key, `C-h'.
- -- Prefix Command: help-command
- This symbol is not a function; its function definition cell holds
- the keymap known as `help-map'. It is defined in `help.el' as
- follows:
- (define-key global-map (string help-char) 'help-command)
- (fset 'help-command help-map)
- -- User Option: help-char
- The value of this variable is the help character--the character
- that Emacs recognizes as meaning Help. By default, its value is
- 8, which stands for `C-h'. When Emacs reads this character, if
- `help-form' is a non-`nil' Lisp expression, it evaluates that
- expression, and displays the result in a window if it is a string.
- Usually the value of `help-form' is `nil'. Then the help
- character has no special meaning at the level of command input, and
- it becomes part of a key sequence in the normal way. The standard
- key binding of `C-h' is a prefix key for several general-purpose
- help features.
- The help character is special after prefix keys, too. If it has no
- binding as a subcommand of the prefix key, it runs
- `describe-prefix-bindings', which displays a list of all the
- subcommands of the prefix key.
- -- User Option: help-event-list
- The value of this variable is a list of event types that serve as
- alternative "help characters". These events are handled just like
- the event specified by `help-char'.
- -- Variable: help-form
- If this variable is non-`nil', its value is a form to evaluate
- whenever the character `help-char' is read. If evaluating the form
- produces a string, that string is displayed.
- A command that calls `read-event', `read-char-choice', or
- `read-char' probably should bind `help-form' to a non-`nil'
- expression while it does input. (The time when you should not do
- this is when `C-h' has some other meaning.) Evaluating this
- expression should result in a string that explains what the input
- is for and how to enter it properly.
- Entry to the minibuffer binds this variable to the value of
- `minibuffer-help-form' (*note Definition of
- minibuffer-help-form::).
- -- Variable: prefix-help-command
- This variable holds a function to print help for a prefix key. The
- function is called when the user types a prefix key followed by
- the help character, and the help character has no binding after
- that prefix. The variable's default value is
- `describe-prefix-bindings'.
- -- Command: describe-prefix-bindings
- This function calls `describe-bindings' to display a list of all
- the subcommands of the prefix key of the most recent key sequence.
- The prefix described consists of all but the last event of that key
- sequence. (The last event is, presumably, the help character.)
- The following two functions are meant for modes that want to provide
- help without relinquishing control, such as the "electric" modes.
- Their names begin with `Helper' to distinguish them from the ordinary
- help functions.
- -- Command: Helper-describe-bindings
- This command pops up a window displaying a help buffer containing a
- listing of all of the key bindings from both the local and global
- keymaps. It works by calling `describe-bindings'.
- -- Command: Helper-help
- This command provides help for the current mode. It prompts the
- user in the minibuffer with the message `Help (Type ? for further
- options)', and then provides assistance in finding out what the key
- bindings are, and what the mode is intended for. It returns `nil'.
- This can be customized by changing the map `Helper-help-map'.
- -- Variable: data-directory
- This variable holds the name of the directory in which Emacs finds
- certain documentation and text files that come with Emacs.
- -- Function: help-buffer
- This function returns the name of the help buffer, which is
- normally `*Help*'; if such a buffer does not exist, it is first
- created.
- -- Macro: with-help-window buffer-name body...
- This macro evaluates the BODY forms, inserting any output they
- produce into a buffer named BUFFER-NAME like
- `with-output-to-temp-buffer' (*note Temporary Displays::).
- (Usually, BUFFER-NAME should be the value returned by the function
- `help-buffer'.) It also puts the specified buffer into Help mode
- and displays a message telling the user how to quit and scroll the
- help window.
- -- Function: help-setup-xref item interactive-p
- This function updates the cross reference data in the `*Help*'
- buffer, which is used to regenerate the help information when the
- user clicks on the `Back' or `Forward' buttons. Most commands
- that use the `*Help*' buffer should invoke this function before
- clearing the buffer. The ITEM argument should have the form
- `(FUNCTION . ARGS)', where FUNCTION is a function to call, with
- argument list ARGS, to regenerate the help buffer. The
- INTERACTIVE-P argument is non-`nil' if the calling command was
- invoked interactively; in that case, the stack of items for the
- `*Help*' buffer's `Back' buttons is cleared.
- *Note describe-symbols example::, for an example of using
- `help-buffer', `with-help-window', and `help-setup-xref'.
- -- Macro: make-help-screen fname help-line help-text help-map
- This macro defines a help command named FNAME that acts like a
- prefix key that shows a list of the subcommands it offers.
- When invoked, FNAME displays HELP-TEXT in a window, then reads and
- executes a key sequence according to HELP-MAP. The string
- HELP-TEXT should describe the bindings available in HELP-MAP.
- The command FNAME is defined to handle a few events itself, by
- scrolling the display of HELP-TEXT. When FNAME reads one of those
- special events, it does the scrolling and then reads another
- event. When it reads an event that is not one of those few, and
- which has a binding in HELP-MAP, it executes that key's binding and
- then returns.
- The argument HELP-LINE should be a single-line summary of the
- alternatives in HELP-MAP. In the current version of Emacs, this
- argument is used only if you set the option `three-step-help' to
- `t'.
- This macro is used in the command `help-for-help' which is the
- binding of `C-h C-h'.
- -- User Option: three-step-help
- If this variable is non-`nil', commands defined with
- `make-help-screen' display their HELP-LINE strings in the echo
- area at first, and display the longer HELP-TEXT strings only if
- the user types the help character again.
- File: elisp, Node: Files, Next: Backups and Auto-Saving, Prev: Documentation, Up: Top
- 25 Files
- ********
- This chapter describes the Emacs Lisp functions and variables to find,
- create, view, save, and otherwise work with files and file directories.
- A few other file-related functions are described in *note Buffers::,
- and those related to backups and auto-saving are described in *note
- Backups and Auto-Saving::.
- Many of the file functions take one or more arguments that are file
- names. A file name is actually a string. Most of these functions
- expand file name arguments by calling `expand-file-name', so that `~'
- is handled correctly, as are relative file names (including `../').
- *Note File Name Expansion::.
- In addition, certain "magic" file names are handled specially. For
- example, when a remote file name is specified, Emacs accesses the file
- over the network via an appropriate protocol (*note Remote Files:
- (emacs)Remote Files.). This handling is done at a very low level, so
- you may assume that all the functions described in this chapter accept
- magic file names as file name arguments, except where noted. *Note
- Magic File Names::, for details.
- When file I/O functions signal Lisp errors, they usually use the
- condition `file-error' (*note Handling Errors::). The error message is
- in most cases obtained from the operating system, according to locale
- `system-message-locale', and decoded using coding system
- `locale-coding-system' (*note Locales::).
- * Menu:
- * Visiting Files:: Reading files into Emacs buffers for editing.
- * Saving Buffers:: Writing changed buffers back into files.
- * Reading from Files:: Reading files into buffers without visiting.
- * Writing to Files:: Writing new files from parts of buffers.
- * File Locks:: Locking and unlocking files, to prevent
- simultaneous editing by two people.
- * Information about Files:: Testing existence, accessibility, size of files.
- * Changing Files:: Renaming files, changing permissions, etc.
- * File Names:: Decomposing and expanding file names.
- * Contents of Directories:: Getting a list of the files in a directory.
- * Create/Delete Dirs:: Creating and Deleting Directories.
- * Magic File Names:: Special handling for certain file names.
- * Format Conversion:: Conversion to and from various file formats.
- File: elisp, Node: Visiting Files, Next: Saving Buffers, Up: Files
- 25.1 Visiting Files
- ===================
- Visiting a file means reading a file into a buffer. Once this is done,
- we say that the buffer is "visiting" that file, and call the file "the
- visited file" of the buffer.
- A file and a buffer are two different things. A file is information
- recorded permanently in the computer (unless you delete it). A buffer,
- on the other hand, is information inside of Emacs that will vanish at
- the end of the editing session (or when you kill the buffer). Usually,
- a buffer contains information that you have copied from a file; then we
- say the buffer is visiting that file. The copy in the buffer is what
- you modify with editing commands. Such changes to the buffer do not
- change the file; therefore, to make the changes permanent, you must
- "save" the buffer, which means copying the altered buffer contents back
- into the file.
- In spite of the distinction between files and buffers, people often
- refer to a file when they mean a buffer and vice-versa. Indeed, we say,
- "I am editing a file", rather than, "I am editing a buffer that I will
- soon save as a file of the same name". Humans do not usually need to
- make the distinction explicit. When dealing with a computer program,
- however, it is good to keep the distinction in mind.
- * Menu:
- * Visiting Functions:: The usual interface functions for visiting.
- * Subroutines of Visiting:: Lower-level subroutines that they use.
- File: elisp, Node: Visiting Functions, Next: Subroutines of Visiting, Up: Visiting Files
- 25.1.1 Functions for Visiting Files
- -----------------------------------
- This section describes the functions normally used to visit files. For
- historical reasons, these functions have names starting with `find-'
- rather than `visit-'. *Note Buffer File Name::, for functions and
- variables that access the visited file name of a buffer or that find an
- existing buffer by its visited file name.
- In a Lisp program, if you want to look at the contents of a file but
- not alter it, the fastest way is to use `insert-file-contents' in a
- temporary buffer. Visiting the file is not necessary and takes longer.
- *Note Reading from Files::.
- -- Command: find-file filename &optional wildcards
- This command selects a buffer visiting the file FILENAME, using an
- existing buffer if there is one, and otherwise creating a new
- buffer and reading the file into it. It also returns that buffer.
- Aside from some technical details, the body of the `find-file'
- function is basically equivalent to:
- (switch-to-buffer (find-file-noselect filename nil nil wildcards))
- (See `switch-to-buffer' in *note Switching Buffers::.)
- If WILDCARDS is non-`nil', which is always true in an interactive
- call, then `find-file' expands wildcard characters in FILENAME and
- visits all the matching files.
- When `find-file' is called interactively, it prompts for FILENAME
- in the minibuffer.
- -- Command: find-file-literally filename
- This command visits FILENAME, like `find-file' does, but it does
- not perform any format conversions (*note Format Conversion::),
- character code conversions (*note Coding Systems::), or end-of-line
- conversions (*note End of line conversion: Coding System Basics.).
- The buffer visiting the file is made unibyte, and its major mode is
- Fundamental mode, regardless of the file name. File local variable
- specifications in the file (*note File Local Variables::) are
- ignored, and automatic decompression and adding a newline at the
- end of the file due to `require-final-newline' (*note
- require-final-newline: Saving Buffers.) are also disabled.
- Note that if Emacs already has a buffer visiting the same file
- non-literally, it will not visit the same file literally, but
- instead just switch to the existing buffer. If you want to be
- sure of accessing a file's contents literally, you should create a
- temporary buffer and then read the file contents into it using
- `insert-file-contents-literally' (*note Reading from Files::).
- -- Function: find-file-noselect filename &optional nowarn rawfile
- wildcards
- This function is the guts of all the file-visiting functions. It
- returns a buffer visiting the file FILENAME. You may make the
- buffer current or display it in a window if you wish, but this
- function does not do so.
- The function returns an existing buffer if there is one; otherwise
- it creates a new buffer and reads the file into it. When
- `find-file-noselect' uses an existing buffer, it first verifies
- that the file has not changed since it was last visited or saved in
- that buffer. If the file has changed, this function asks the user
- whether to reread the changed file. If the user says `yes', any
- edits previously made in the buffer are lost.
- Reading the file involves decoding the file's contents (*note
- Coding Systems::), including end-of-line conversion, and format
- conversion (*note Format Conversion::). If WILDCARDS is non-`nil',
- then `find-file-noselect' expands wildcard characters in FILENAME
- and visits all the matching files.
- This function displays warning or advisory messages in various
- peculiar cases, unless the optional argument NOWARN is non-`nil'.
- For example, if it needs to create a buffer, and there is no file
- named FILENAME, it displays the message `(New file)' in the echo
- area, and leaves the buffer empty.
- The `find-file-noselect' function normally calls `after-find-file'
- after reading the file (*note Subroutines of Visiting::). That
- function sets the buffer major mode, parses local variables, warns
- the user if there exists an auto-save file more recent than the
- file just visited, and finishes by running the functions in
- `find-file-hook'.
- If the optional argument RAWFILE is non-`nil', then
- `after-find-file' is not called, and the
- `find-file-not-found-functions' are not run in case of failure.
- What's more, a non-`nil' RAWFILE value suppresses coding system
- conversion and format conversion.
- The `find-file-noselect' function usually returns the buffer that
- is visiting the file FILENAME. But, if wildcards are actually
- used and expanded, it returns a list of buffers that are visiting
- the various files.
- (find-file-noselect "/etc/fstab")
- => #<buffer fstab>
- -- Command: find-file-other-window filename &optional wildcards
- This command selects a buffer visiting the file FILENAME, but does
- so in a window other than the selected window. It may use another
- existing window or split a window; see *note Switching Buffers::.
- When this command is called interactively, it prompts for FILENAME.
- -- Command: find-file-read-only filename &optional wildcards
- This command selects a buffer visiting the file FILENAME, like
- `find-file', but it marks the buffer as read-only. *Note Read
- Only Buffers::, for related functions and variables.
- When this command is called interactively, it prompts for FILENAME.
- -- User Option: find-file-wildcards
- If this variable is non-`nil', then the various `find-file'
- commands check for wildcard characters and visit all the files that
- match them (when invoked interactively or when their WILDCARDS
- argument is non-`nil'). If this option is `nil', then the
- `find-file' commands ignore their WILDCARDS argument and never
- treat wildcard characters specially.
- -- User Option: find-file-hook
- The value of this variable is a list of functions to be called
- after a file is visited. The file's local-variables specification
- (if any) will have been processed before the hooks are run. The
- buffer visiting the file is current when the hook functions are
- run.
- This variable is a normal hook. *Note Hooks::.
- -- Variable: find-file-not-found-functions
- The value of this variable is a list of functions to be called when
- `find-file' or `find-file-noselect' is passed a nonexistent file
- name. `find-file-noselect' calls these functions as soon as it
- detects a nonexistent file. It calls them in the order of the
- list, until one of them returns non-`nil'. `buffer-file-name' is
- already set up.
- This is not a normal hook because the values of the functions are
- used, and in many cases only some of the functions are called.
- -- Variable: find-file-literally
- This buffer-local variable, if set to a non-`nil' value, makes
- `save-buffer' behave as if the buffer were visiting its file
- literally, i.e. without conversions of any kind. The command
- `find-file-literally' sets this variable's local value, but other
- equivalent functions and commands can do that as well, e.g. to
- avoid automatic addition of a newline at the end of the file.
- This variable is permanent local, so it is unaffected by changes
- of major modes.
- File: elisp, Node: Subroutines of Visiting, Prev: Visiting Functions, Up: Visiting Files
- 25.1.2 Subroutines of Visiting
- ------------------------------
- The `find-file-noselect' function uses two important subroutines which
- are sometimes useful in user Lisp code: `create-file-buffer' and
- `after-find-file'. This section explains how to use them.
- -- Function: create-file-buffer filename
- This function creates a suitably named buffer for visiting
- FILENAME, and returns it. It uses FILENAME (sans directory) as
- the name if that name is free; otherwise, it appends a string such
- as `<2>' to get an unused name. See also *note Creating Buffers::.
- *Please note:* `create-file-buffer' does _not_ associate the new
- buffer with a file and does not select the buffer. It also does
- not use the default major mode.
- (create-file-buffer "foo")
- => #<buffer foo>
- (create-file-buffer "foo")
- => #<buffer foo<2>>
- (create-file-buffer "foo")
- => #<buffer foo<3>>
- This function is used by `find-file-noselect'. It uses
- `generate-new-buffer' (*note Creating Buffers::).
- -- Function: after-find-file &optional error warn noauto
- after-find-file-from-revert-buffer nomodes
- This function sets the buffer major mode, and parses local
- variables (*note Auto Major Mode::). It is called by
- `find-file-noselect' and by the default revert function (*note
- Reverting::).
- If reading the file got an error because the file does not exist,
- but its directory does exist, the caller should pass a non-`nil'
- value for ERROR. In that case, `after-find-file' issues a warning:
- `(New file)'. For more serious errors, the caller should usually
- not call `after-find-file'.
- If WARN is non-`nil', then this function issues a warning if an
- auto-save file exists and is more recent than the visited file.
- If NOAUTO is non-`nil', that says not to enable or disable
- Auto-Save mode. The mode remains enabled if it was enabled before.
- If AFTER-FIND-FILE-FROM-REVERT-BUFFER is non-`nil', that means
- this call was from `revert-buffer'. This has no direct effect,
- but some mode functions and hook functions check the value of this
- variable.
- If NOMODES is non-`nil', that means don't alter the buffer's major
- mode, don't process local variables specifications in the file,
- and don't run `find-file-hook'. This feature is used by
- `revert-buffer' in some cases.
- The last thing `after-find-file' does is call all the functions in
- the list `find-file-hook'.
- File: elisp, Node: Saving Buffers, Next: Reading from Files, Prev: Visiting Files, Up: Files
- 25.2 Saving Buffers
- ===================
- When you edit a file in Emacs, you are actually working on a buffer
- that is visiting that file--that is, the contents of the file are
- copied into the buffer and the copy is what you edit. Changes to the
- buffer do not change the file until you "save" the buffer, which means
- copying the contents of the buffer into the file.
- -- Command: save-buffer &optional backup-option
- This function saves the contents of the current buffer in its
- visited file if the buffer has been modified since it was last
- visited or saved. Otherwise it does nothing.
- `save-buffer' is responsible for making backup files. Normally,
- BACKUP-OPTION is `nil', and `save-buffer' makes a backup file only
- if this is the first save since visiting the file. Other values
- for BACKUP-OPTION request the making of backup files in other
- circumstances:
- * With an argument of 4 or 64, reflecting 1 or 3 `C-u''s, the
- `save-buffer' function marks this version of the file to be
- backed up when the buffer is next saved.
- * With an argument of 16 or 64, reflecting 2 or 3 `C-u''s, the
- `save-buffer' function unconditionally backs up the previous
- version of the file before saving it.
- * With an argument of 0, unconditionally do _not_ make any
- backup file.
- -- Command: save-some-buffers &optional save-silently-p pred
- This command saves some modified file-visiting buffers. Normally
- it asks the user about each buffer. But if SAVE-SILENTLY-P is
- non-`nil', it saves all the file-visiting buffers without querying
- the user.
- The optional PRED argument controls which buffers to ask about (or
- to save silently if SAVE-SILENTLY-P is non-`nil'). If it is
- `nil', that means to ask only about file-visiting buffers. If it
- is `t', that means also offer to save certain other non-file
- buffers--those that have a non-`nil' buffer-local value of
- `buffer-offer-save' (*note Killing Buffers::). A user who says
- `yes' to saving a non-file buffer is asked to specify the file
- name to use. The `save-buffers-kill-emacs' function passes the
- value `t' for PRED.
- If PRED is neither `t' nor `nil', then it should be a function of
- no arguments. It will be called in each buffer to decide whether
- to offer to save that buffer. If it returns a non-`nil' value in
- a certain buffer, that means do offer to save that buffer.
- -- Command: write-file filename &optional confirm
- This function writes the current buffer into file FILENAME, makes
- the buffer visit that file, and marks it not modified. Then it
- renames the buffer based on FILENAME, appending a string like `<2>'
- if necessary to make a unique buffer name. It does most of this
- work by calling `set-visited-file-name' (*note Buffer File Name::)
- and `save-buffer'.
- If CONFIRM is non-`nil', that means to ask for confirmation before
- overwriting an existing file. Interactively, confirmation is
- required, unless the user supplies a prefix argument.
- If FILENAME is an existing directory, or a symbolic link to one,
- `write-file' uses the name of the visited file, in directory
- FILENAME. If the buffer is not visiting a file, it uses the
- buffer name instead.
- Saving a buffer runs several hooks. It also performs format
- conversion (*note Format Conversion::).
- -- Variable: write-file-functions
- The value of this variable is a list of functions to be called
- before writing out a buffer to its visited file. If one of them
- returns non-`nil', the file is considered already written and the
- rest of the functions are not called, nor is the usual code for
- writing the file executed.
- If a function in `write-file-functions' returns non-`nil', it is
- responsible for making a backup file (if that is appropriate). To
- do so, execute the following code:
- (or buffer-backed-up (backup-buffer))
- You might wish to save the file modes value returned by
- `backup-buffer' and use that (if non-`nil') to set the mode bits
- of the file that you write. This is what `save-buffer' normally
- does. *Note Making Backup Files: Making Backups.
- The hook functions in `write-file-functions' are also responsible
- for encoding the data (if desired): they must choose a suitable
- coding system and end-of-line conversion (*note Lisp and Coding
- Systems::), perform the encoding (*note Explicit Encoding::), and
- set `last-coding-system-used' to the coding system that was used
- (*note Encoding and I/O::).
- If you set this hook locally in a buffer, it is assumed to be
- associated with the file or the way the contents of the buffer were
- obtained. Thus the variable is marked as a permanent local, so
- that changing the major mode does not alter a buffer-local value.
- On the other hand, calling `set-visited-file-name' will reset it.
- If this is not what you want, you might like to use
- `write-contents-functions' instead.
- Even though this is not a normal hook, you can use `add-hook' and
- `remove-hook' to manipulate the list. *Note Hooks::.
- -- Variable: write-contents-functions
- This works just like `write-file-functions', but it is intended
- for hooks that pertain to the buffer's contents, not to the
- particular visited file or its location. Such hooks are usually
- set up by major modes, as buffer-local bindings for this variable.
- This variable automatically becomes buffer-local whenever it is
- set; switching to a new major mode always resets this variable,
- but calling `set-visited-file-name' does not.
- If any of the functions in this hook returns non-`nil', the file
- is considered already written and the rest are not called and
- neither are the functions in `write-file-functions'.
- -- User Option: before-save-hook
- This normal hook runs before a buffer is saved in its visited file,
- regardless of whether that is done normally or by one of the hooks
- described above. For instance, the `copyright.el' program uses
- this hook to make sure the file you are saving has the current
- year in its copyright notice.
- -- User Option: after-save-hook
- This normal hook runs after a buffer has been saved in its visited
- file. One use of this hook is in Fast Lock mode; it uses this
- hook to save the highlighting information in a cache file.
- -- User Option: file-precious-flag
- If this variable is non-`nil', then `save-buffer' protects against
- I/O errors while saving by writing the new file to a temporary
- name instead of the name it is supposed to have, and then renaming
- it to the intended name after it is clear there are no errors.
- This procedure prevents problems such as a lack of disk space from
- resulting in an invalid file.
- As a side effect, backups are necessarily made by copying. *Note
- Rename or Copy::. Yet, at the same time, saving a precious file
- always breaks all hard links between the file you save and other
- file names.
- Some modes give this variable a non-`nil' buffer-local value in
- particular buffers.
- -- User Option: require-final-newline
- This variable determines whether files may be written out that do
- _not_ end with a newline. If the value of the variable is `t',
- then `save-buffer' silently adds a newline at the end of the
- buffer whenever it does not already end in one. If the value is
- `visit', Emacs adds a missing newline just after it visits the
- file. If the value is `visit-save', Emacs adds a missing newline
- both on visiting and on saving. For any other non-`nil' value,
- `save-buffer' asks the user whether to add a newline each time the
- case arises.
- If the value of the variable is `nil', then `save-buffer' doesn't
- add newlines at all. `nil' is the default value, but a few major
- modes set it to `t' in particular buffers.
- See also the function `set-visited-file-name' (*note Buffer File
- Name::).
- File: elisp, Node: Reading from Files, Next: Writing to Files, Prev: Saving Buffers, Up: Files
- 25.3 Reading from Files
- =======================
- You can copy a file from the disk and insert it into a buffer using the
- `insert-file-contents' function. Don't use the user-level command
- `insert-file' in a Lisp program, as that sets the mark.
- -- Function: insert-file-contents filename &optional visit beg end
- replace
- This function inserts the contents of file FILENAME into the
- current buffer after point. It returns a list of the absolute
- file name and the length of the data inserted. An error is
- signaled if FILENAME is not the name of a file that can be read.
- This function checks the file contents against the defined file
- formats, and converts the file contents if appropriate and also
- calls the functions in the list `after-insert-file-functions'.
- *Note Format Conversion::. Normally, one of the functions in the
- `after-insert-file-functions' list determines the coding system
- (*note Coding Systems::) used for decoding the file's contents,
- including end-of-line conversion. However, if the file contains
- null bytes, it is by default visited without any code conversions.
- *Note inhibit-null-byte-detection: Lisp and Coding Systems.
- If VISIT is non-`nil', this function additionally marks the buffer
- as unmodified and sets up various fields in the buffer so that it
- is visiting the file FILENAME: these include the buffer's visited
- file name and its last save file modtime. This feature is used by
- `find-file-noselect' and you probably should not use it yourself.
- If BEG and END are non-`nil', they should be integers specifying
- the portion of the file to insert. In this case, VISIT must be
- `nil'. For example,
- (insert-file-contents filename nil 0 500)
- inserts the first 500 characters of a file.
- If the argument REPLACE is non-`nil', it means to replace the
- contents of the buffer (actually, just the accessible portion)
- with the contents of the file. This is better than simply
- deleting the buffer contents and inserting the whole file, because
- (1) it preserves some marker positions and (2) it puts less data
- in the undo list.
- It is possible to read a special file (such as a FIFO or an I/O
- device) with `insert-file-contents', as long as REPLACE and VISIT
- are `nil'.
- -- Function: insert-file-contents-literally filename &optional visit
- beg end replace
- This function works like `insert-file-contents' except that it
- does not run `find-file-hook', and does not do format decoding,
- character code conversion, automatic uncompression, and so on.
- If you want to pass a file name to another process so that another
- program can read the file, use the function `file-local-copy'; see
- *note Magic File Names::.
- File: elisp, Node: Writing to Files, Next: File Locks, Prev: Reading from Files, Up: Files
- 25.4 Writing to Files
- =====================
- You can write the contents of a buffer, or part of a buffer, directly
- to a file on disk using the `append-to-file' and `write-region'
- functions. Don't use these functions to write to files that are being
- visited; that could cause confusion in the mechanisms for visiting.
- -- Command: append-to-file start end filename
- This function appends the contents of the region delimited by
- START and END in the current buffer to the end of file FILENAME.
- If that file does not exist, it is created. This function returns
- `nil'.
- An error is signaled if FILENAME specifies a nonwritable file, or
- a nonexistent file in a directory where files cannot be created.
- When called from Lisp, this function is completely equivalent to:
- (write-region start end filename t)
- -- Command: write-region start end filename &optional append visit
- lockname mustbenew
- This function writes the region delimited by START and END in the
- current buffer into the file specified by FILENAME.
- If START is `nil', then the command writes the entire buffer
- contents (_not_ just the accessible portion) to the file and
- ignores END.
- If START is a string, then `write-region' writes or appends that
- string, rather than text from the buffer. END is ignored in this
- case.
- If APPEND is non-`nil', then the specified text is appended to the
- existing file contents (if any). If APPEND is an integer,
- `write-region' seeks to that byte offset from the start of the
- file and writes the data from there.
- If MUSTBENEW is non-`nil', then `write-region' asks for
- confirmation if FILENAME names an existing file. If MUSTBENEW is
- the symbol `excl', then `write-region' does not ask for
- confirmation, but instead it signals an error
- `file-already-exists' if the file already exists.
- The test for an existing file, when MUSTBENEW is `excl', uses a
- special system feature. At least for files on a local disk, there
- is no chance that some other program could create a file of the
- same name before Emacs does, without Emacs's noticing.
- If VISIT is `t', then Emacs establishes an association between the
- buffer and the file: the buffer is then visiting that file. It
- also sets the last file modification time for the current buffer to
- FILENAME's modtime, and marks the buffer as not modified. This
- feature is used by `save-buffer', but you probably should not use
- it yourself.
- If VISIT is a string, it specifies the file name to visit. This
- way, you can write the data to one file (FILENAME) while recording
- the buffer as visiting another file (VISIT). The argument VISIT
- is used in the echo area message and also for file locking; VISIT
- is stored in `buffer-file-name'. This feature is used to
- implement `file-precious-flag'; don't use it yourself unless you
- really know what you're doing.
- The optional argument LOCKNAME, if non-`nil', specifies the file
- name to use for purposes of locking and unlocking, overriding
- FILENAME and VISIT for that purpose.
- The function `write-region' converts the data which it writes to
- the appropriate file formats specified by `buffer-file-format' and
- also calls the functions in the list
- `write-region-annotate-functions'. *Note Format Conversion::.
- Normally, `write-region' displays the message `Wrote FILENAME' in
- the echo area. If VISIT is neither `t' nor `nil' nor a string,
- then this message is inhibited. This feature is useful for
- programs that use files for internal purposes, files that the user
- does not need to know about.
- -- Macro: with-temp-file file body...
- The `with-temp-file' macro evaluates the BODY forms with a
- temporary buffer as the current buffer; then, at the end, it
- writes the buffer contents into file FILE. It kills the temporary
- buffer when finished, restoring the buffer that was current before
- the `with-temp-file' form. Then it returns the value of the last
- form in BODY.
- The current buffer is restored even in case of an abnormal exit via
- `throw' or error (*note Nonlocal Exits::).
- See also `with-temp-buffer' in *note The Current Buffer:
- Definition of with-temp-buffer.
- File: elisp, Node: File Locks, Next: Information about Files, Prev: Writing to Files, Up: Files
- 25.5 File Locks
- ===============
- When two users edit the same file at the same time, they are likely to
- interfere with each other. Emacs tries to prevent this situation from
- arising by recording a "file lock" when a file is being modified.
- (File locks are not implemented on Microsoft systems.) Emacs can then
- detect the first attempt to modify a buffer visiting a file that is
- locked by another Emacs job, and ask the user what to do. The file
- lock is really a file, a symbolic link with a special name, stored in
- the same directory as the file you are editing.
- When you access files using NFS, there may be a small probability
- that you and another user will both lock the same file "simultaneously".
- If this happens, it is possible for the two users to make changes
- simultaneously, but Emacs will still warn the user who saves second.
- Also, the detection of modification of a buffer visiting a file changed
- on disk catches some cases of simultaneous editing; see *note
- Modification Time::.
- -- Function: file-locked-p filename
- This function returns `nil' if the file FILENAME is not locked.
- It returns `t' if it is locked by this Emacs process, and it
- returns the name of the user who has locked it if it is locked by
- some other job.
- (file-locked-p "foo")
- => nil
- -- Function: lock-buffer &optional filename
- This function locks the file FILENAME, if the current buffer is
- modified. The argument FILENAME defaults to the current buffer's
- visited file. Nothing is done if the current buffer is not
- visiting a file, or is not modified, or if the system does not
- support locking.
- -- Function: unlock-buffer
- This function unlocks the file being visited in the current buffer,
- if the buffer is modified. If the buffer is not modified, then
- the file should not be locked, so this function does nothing. It
- also does nothing if the current buffer is not visiting a file, or
- if the system does not support locking.
- File locking is not supported on some systems. On systems that do
- not support it, the functions `lock-buffer', `unlock-buffer' and
- `file-locked-p' do nothing and return `nil'.
- -- Function: ask-user-about-lock file other-user
- This function is called when the user tries to modify FILE, but it
- is locked by another user named OTHER-USER. The default
- definition of this function asks the user to say what to do. The
- value this function returns determines what Emacs does next:
- * A value of `t' says to grab the lock on the file. Then this
- user may edit the file and OTHER-USER loses the lock.
- * A value of `nil' says to ignore the lock and let this user
- edit the file anyway.
- * This function may instead signal a `file-locked' error, in
- which case the change that the user was about to make does
- not take place.
- The error message for this error looks like this:
- error--> File is locked: FILE OTHER-USER
- where `file' is the name of the file and OTHER-USER is the
- name of the user who has locked the file.
- If you wish, you can replace the `ask-user-about-lock' function
- with your own version that makes the decision in another way. The
- code for its usual definition is in `userlock.el'.
- File: elisp, Node: Information about Files, Next: Changing Files, Prev: File Locks, Up: Files
- 25.6 Information about Files
- ============================
- The functions described in this section all operate on strings that
- designate file names. With a few exceptions, all the functions have
- names that begin with the word `file'. These functions all return
- information about actual files or directories, so their arguments must
- all exist as actual files or directories unless otherwise noted.
- * Menu:
- * Testing Accessibility:: Is a given file readable? Writable?
- * Kinds of Files:: Is it a directory? A symbolic link?
- * Truenames:: Eliminating symbolic links from a file name.
- * File Attributes:: How large is it? Any other names? Etc.
- * Locating Files:: How to find a file in standard places.
- File: elisp, Node: Testing Accessibility, Next: Kinds of Files, Up: Information about Files
- 25.6.1 Testing Accessibility
- ----------------------------
- These functions test for permission to access a file in specific ways.
- Unless explicitly stated otherwise, they recursively follow symbolic
- links for their file name arguments, at all levels (at the level of the
- file itself and at all levels of parent directories).
- -- Function: file-exists-p filename
- This function returns `t' if a file named FILENAME appears to
- exist. This does not mean you can necessarily read the file, only
- that you can find out its attributes. (On Unix and GNU/Linux,
- this is true if the file exists and you have execute permission on
- the containing directories, regardless of the permissions of the
- file itself.)
- If the file does not exist, or if fascist access control policies
- prevent you from finding the attributes of the file, this function
- returns `nil'.
- Directories are files, so `file-exists-p' returns `t' when given a
- directory name. However, symbolic links are treated specially;
- `file-exists-p' returns `t' for a symbolic link name only if the
- target file exists.
- -- Function: file-readable-p filename
- This function returns `t' if a file named FILENAME exists and you
- can read it. It returns `nil' otherwise.
- (file-readable-p "files.texi")
- => t
- (file-exists-p "/usr/spool/mqueue")
- => t
- (file-readable-p "/usr/spool/mqueue")
- => nil
- -- Function: file-executable-p filename
- This function returns `t' if a file named FILENAME exists and you
- can execute it. It returns `nil' otherwise. On Unix and
- GNU/Linux, if the file is a directory, execute permission means
- you can check the existence and attributes of files inside the
- directory, and open those files if their modes permit.
- -- Function: file-writable-p filename
- This function returns `t' if the file FILENAME can be written or
- created by you, and `nil' otherwise. A file is writable if the
- file exists and you can write it. It is creatable if it does not
- exist, but the specified directory does exist and you can write in
- that directory.
- In the third example below, `foo' is not writable because the
- parent directory does not exist, even though the user could create
- such a directory.
- (file-writable-p "~/foo")
- => t
- (file-writable-p "/foo")
- => nil
- (file-writable-p "~/no-such-dir/foo")
- => nil
- -- Function: file-accessible-directory-p dirname
- This function returns `t' if you have permission to open existing
- files in the directory whose name as a file is DIRNAME; otherwise
- (or if there is no such directory), it returns `nil'. The value
- of DIRNAME may be either a directory name (such as `/foo/') or the
- file name of a file which is a directory (such as `/foo', without
- the final slash).
- Example: after the following,
- (file-accessible-directory-p "/foo")
- => nil
- we can deduce that any attempt to read a file in `/foo/' will give
- an error.
- -- Function: access-file filename string
- This function opens file FILENAME for reading, then closes it and
- returns `nil'. However, if the open fails, it signals an error
- using STRING as the error message text.
- -- Function: file-ownership-preserved-p filename
- This function returns `t' if deleting the file FILENAME and then
- creating it anew would keep the file's owner unchanged. It also
- returns `t' for nonexistent files.
- If FILENAME is a symbolic link, then, unlike the other functions
- discussed here, `file-ownership-preserved-p' does _not_ replace
- FILENAME with its target. However, it does recursively follow
- symbolic links at all levels of parent directories.
- -- Function: file-newer-than-file-p filename1 filename2
- This function returns `t' if the file FILENAME1 is newer than file
- FILENAME2. If FILENAME1 does not exist, it returns `nil'. If
- FILENAME1 does exist, but FILENAME2 does not, it returns `t'.
- In the following example, assume that the file `aug-19' was written
- on the 19th, `aug-20' was written on the 20th, and the file
- `no-file' doesn't exist at all.
- (file-newer-than-file-p "aug-19" "aug-20")
- => nil
- (file-newer-than-file-p "aug-20" "aug-19")
- => t
- (file-newer-than-file-p "aug-19" "no-file")
- => t
- (file-newer-than-file-p "no-file" "aug-19")
- => nil
- You can use `file-attributes' to get a file's last modification
- time as a list of two numbers. *Note File Attributes::.
- File: elisp, Node: Kinds of Files, Next: Truenames, Prev: Testing Accessibility, Up: Information about Files
- 25.6.2 Distinguishing Kinds of Files
- ------------------------------------
- This section describes how to distinguish various kinds of files, such
- as directories, symbolic links, and ordinary files.
- -- Function: file-symlink-p filename
- If the file FILENAME is a symbolic link, the `file-symlink-p'
- function returns the (non-recursive) link target as a string.
- (Determining the file name that the link points to from the target
- is nontrivial.) First, this function recursively follows symbolic
- links at all levels of parent directories.
- If the file FILENAME is not a symbolic link (or there is no such
- file), `file-symlink-p' returns `nil'.
- (file-symlink-p "foo")
- => nil
- (file-symlink-p "sym-link")
- => "foo"
- (file-symlink-p "sym-link2")
- => "sym-link"
- (file-symlink-p "/bin")
- => "/pub/bin"
- The next two functions recursively follow symbolic links at all
- levels for FILENAME.
- -- Function: file-directory-p filename
- This function returns `t' if FILENAME is the name of an existing
- directory, `nil' otherwise.
- (file-directory-p "~rms")
- => t
- (file-directory-p "~rms/lewis/files.texi")
- => nil
- (file-directory-p "~rms/lewis/no-such-file")
- => nil
- (file-directory-p "$HOME")
- => nil
- (file-directory-p
- (substitute-in-file-name "$HOME"))
- => t
- -- Function: file-regular-p filename
- This function returns `t' if the file FILENAME exists and is a
- regular file (not a directory, named pipe, terminal, or other I/O
- device).
- -- Function: file-equal-p file1 file2
- This function returns `t' if the files FILE1 and FILE2 name the
- same file. If FILE1 or FILE2 does not exist, the return value is
- unspecified.
- -- Function: file-in-directory-p file dir
- This function returns `t' if FILE is a file in directory DIR, or
- in a subdirectory of DIR. It also returns `t' if FILE and DIR are
- the same directory. It compares the `file-truename' values of the
- two directories (*note Truenames::). If DIR does not name an
- existing directory, the return value is `nil'.
- File: elisp, Node: Truenames, Next: File Attributes, Prev: Kinds of Files, Up: Information about Files
- 25.6.3 Truenames
- ----------------
- The "truename" of a file is the name that you get by following symbolic
- links at all levels until none remain, then simplifying away `.' and
- `..' appearing as name components. This results in a sort of canonical
- name for the file. A file does not always have a unique truename; the
- number of distinct truenames a file has is equal to the number of hard
- links to the file. However, truenames are useful because they
- eliminate symbolic links as a cause of name variation.
- -- Function: file-truename filename
- This function returns the truename of the file FILENAME. If the
- argument is not an absolute file name, this function first expands
- it against `default-directory'.
- This function does not expand environment variables. Only
- `substitute-in-file-name' does that. *Note Definition of
- substitute-in-file-name::.
- If you may need to follow symbolic links preceding `..' appearing
- as a name component, you should make sure to call `file-truename'
- without prior direct or indirect calls to `expand-file-name', as
- otherwise the file name component immediately preceding `..' will
- be "simplified away" before `file-truename' is called. To
- eliminate the need for a call to `expand-file-name',
- `file-truename' handles `~' in the same way that
- `expand-file-name' does. *Note Functions that Expand Filenames:
- File Name Expansion.
- -- Function: file-chase-links filename &optional limit
- This function follows symbolic links, starting with FILENAME,
- until it finds a file name which is not the name of a symbolic
- link. Then it returns that file name. This function does _not_
- follow symbolic links at the level of parent directories.
- If you specify a number for LIMIT, then after chasing through that
- many links, the function just returns what it has even if that is
- still a symbolic link.
- To illustrate the difference between `file-chase-links' and
- `file-truename', suppose that `/usr/foo' is a symbolic link to the
- directory `/home/foo', and `/home/foo/hello' is an ordinary file (or at
- least, not a symbolic link) or nonexistent. Then we would have:
- (file-chase-links "/usr/foo/hello")
- ;; This does not follow the links in the parent directories.
- => "/usr/foo/hello"
- (file-truename "/usr/foo/hello")
- ;; Assuming that `/home' is not a symbolic link.
- => "/home/foo/hello"
- *Note Buffer File Name::, for related information.
- File: elisp, Node: File Attributes, Next: Locating Files, Prev: Truenames, Up: Information about Files
- 25.6.4 Other Information about Files
- ------------------------------------
- This section describes the functions for getting detailed information
- about a file, other than its contents. This information includes the
- mode bits that control access permissions, the owner and group numbers,
- the number of names, the inode number, the size, and the times of
- access and modification.
- -- Function: file-modes filename
- This function returns the "mode bits" describing the "file
- permissions" of FILENAME, as an integer. It recursively follows
- symbolic links in FILENAME at all levels. If FILENAME does not
- exist, the return value is `nil'.
- *Note File Permissions: (coreutils)File Permissions, for a
- description of mode bits. If the low-order bit is 1, then the
- file is executable by all users, if the second-lowest-order bit is
- 1, then the file is writable by all users, etc. The highest value
- returnable is 4095 (7777 octal), meaning that everyone has read,
- write, and execute permission, that the SUID bit is set for both
- others and group, and that the sticky bit is set.
- (file-modes "~/junk/diffs")
- => 492 ; Decimal integer.
- (format "%o" 492)
- => "754" ; Convert to octal.
- (set-file-modes "~/junk/diffs" #o666)
- => nil
- % ls -l diffs
- -rw-rw-rw- 1 lewis 0 3063 Oct 30 16:00 diffs
- *Note Changing Files::, for functions that change file permissions,
- such as `set-file-modes'.
- *MS-DOS note:* On MS-DOS, there is no such thing as an
- "executable" file mode bit. So `file-modes' considers a file
- executable if its name ends in one of the standard executable
- extensions, such as `.com', `.bat', `.exe', and some others.
- Files that begin with the Unix-standard `#!' signature, such as
- shell and Perl scripts, are also considered executable.
- Directories are also reported as executable, for compatibility with
- Unix. These conventions are also followed by `file-attributes',
- below.
- If the FILENAME argument to the next two functions is a symbolic
- link, then these function do _not_ replace it with its target.
- However, they both recursively follow symbolic links at all levels of
- parent directories.
- -- Function: file-nlinks filename
- This functions returns the number of names (i.e., hard links) that
- file FILENAME has. If the file does not exist, then this function
- returns `nil'. Note that symbolic links have no effect on this
- function, because they are not considered to be names of the files
- they link to.
- % ls -l foo*
- -rw-rw-rw- 2 rms 4 Aug 19 01:27 foo
- -rw-rw-rw- 2 rms 4 Aug 19 01:27 foo1
- (file-nlinks "foo")
- => 2
- (file-nlinks "doesnt-exist")
- => nil
- -- Function: file-attributes filename &optional id-format
- This function returns a list of attributes of file FILENAME. If
- the specified file cannot be opened, it returns `nil'. The
- optional parameter ID-FORMAT specifies the preferred format of
- attributes UID and GID (see below)--the valid values are `'string'
- and `'integer'. The latter is the default, but we plan to change
- that, so you should specify a non-`nil' value for ID-FORMAT if you
- use the returned UID or GID.
- The elements of the list, in order, are:
- 0. `t' for a directory, a string for a symbolic link (the name
- linked to), or `nil' for a text file.
- 1. The number of names the file has. Alternate names, also
- known as hard links, can be created by using the
- `add-name-to-file' function (*note Changing Files::).
- 2. The file's UID, normally as a string. However, if it does
- not correspond to a named user, the value is an integer or a
- floating point number.
- 3. The file's GID, likewise.
- 4. The time of last access, as a list of two integers. The
- first integer has the high-order 16 bits of time, the second
- has the low 16 bits. (This is similar to the value of
- `current-time'; see *note Time of Day::.) Note that on some
- FAT-based filesystems, only the date of last access is
- recorded, so this time will always hold the midnight of the
- day of last access.
- 5. The time of last modification as a list of two integers (as
- above). This is the last time when the file's contents were
- modified.
- 6. The time of last status change as a list of two integers (as
- above). This is the time of the last change to the file's
- access mode bits, its owner and group, and other information
- recorded in the filesystem for the file, beyond the file's
- contents.
- 7. The size of the file in bytes. If the size is too large to
- fit in a Lisp integer, this is a floating point number.
- 8. The file's modes, as a string of ten letters or dashes, as in
- `ls -l'.
- 9. `t' if the file's GID would change if file were deleted and
- recreated; `nil' otherwise.
- 10. The file's inode number. If possible, this is an integer.
- If the inode number is too large to be represented as an
- integer in Emacs Lisp but dividing it by 2^16 yields a
- representable integer, then the value has the form `(HIGH .
- LOW)', where LOW holds the low 16 bits. If the inode number
- is too wide for even that, the value is of the form `(HIGH
- MIDDLE . LOW)', where `high' holds the high bits, MIDDLE the
- middle 24 bits, and LOW the low 16 bits.
- 11. The filesystem number of the device that the file is on.
- Depending on the magnitude of the value, this can be either
- an integer or a cons cell, in the same manner as the inode
- number. This element and the file's inode number together
- give enough information to distinguish any two files on the
- system--no two files can have the same values for both of
- these numbers.
- For example, here are the file attributes for `files.texi':
- (file-attributes "files.texi" 'string)
- => (nil 1 "lh" "users"
- (19145 42977)
- (19141 59576)
- (18340 17300)
- 122295 "-rw-rw-rw-"
- nil (5888 2 . 43978)
- (15479 . 46724))
- and here is how the result is interpreted:
- `nil'
- is neither a directory nor a symbolic link.
- `1'
- has only one name (the name `files.texi' in the current
- default directory).
- `"lh"'
- is owned by the user with name "lh".
- `"users"'
- is in the group with name "users".
- `(19145 42977)'
- was last accessed on Oct 5 2009, at 10:01:37.
- `(19141 59576)'
- last had its contents modified on Oct 2 2009, at 13:49:12.
- `(18340 17300)'
- last had its status changed on Feb 2 2008, at 12:19:00.
- `122295'
- is 122295 bytes long. (It may not contain 122295 characters,
- though, if some of the bytes belong to multibyte sequences,
- and also if the end-of-line format is CR-LF.)
- `"-rw-rw-rw-"'
- has a mode of read and write access for the owner, group, and
- world.
- `nil'
- would retain the same GID if it were recreated.
- `(5888 2 . 43978)'
- has an inode number of 6473924464520138.
- `(15479 . 46724)'
- is on the file-system device whose number is 1014478468.
- SELinux is a Linux kernel feature which provides more sophisticated
- file access controls than ordinary "Unix-style" file permissions. If
- Emacs has been compiled with SELinux support on a system with SELinux
- enabled, you can use the function `file-selinux-context' to retrieve a
- file's SELinux security context. For the function
- `set-file-selinux-context', see *note Changing Files::.
- -- Function: file-selinux-context filename
- This function returns the SELinux security context of the file
- FILENAME. This return value is a list of the form `(USER ROLE
- TYPE RANGE)', whose elements are the context's user, role, type,
- and range respectively, as Lisp strings. See the SELinux
- documentation for details about what these actually mean.
- If the file does not exist or is inaccessible, or if the system
- does not support SELinux, or if Emacs was not compiled with SELinux
- support, then the return value is `(nil nil nil nil)'.
- File: elisp, Node: Locating Files, Prev: File Attributes, Up: Information about Files
- 25.6.5 How to Locate Files in Standard Places
- ---------------------------------------------
- This section explains how to search for a file in a list of directories
- (a "path"), or for an executable file in the standard list of
- executable file directories.
- To search for a user-specific configuration file, *Note Standard
- File Names::, for the `locate-user-emacs-file' function.
- -- Function: locate-file filename path &optional suffixes predicate
- This function searches for a file whose name is FILENAME in a list
- of directories given by PATH, trying the suffixes in SUFFIXES. If
- it finds such a file, it returns the file's absolute file name
- (*note Relative File Names::); otherwise it returns `nil'.
- The optional argument SUFFIXES gives the list of file-name
- suffixes to append to FILENAME when searching. `locate-file'
- tries each possible directory with each of these suffixes. If
- SUFFIXES is `nil', or `("")', then there are no suffixes, and
- FILENAME is used only as-is. Typical values of SUFFIXES are
- `exec-suffixes' (*note Subprocess Creation::), `load-suffixes',
- `load-file-rep-suffixes' and the return value of the function
- `get-load-suffixes' (*note Load Suffixes::).
- Typical values for PATH are `exec-path' (*note Subprocess
- Creation::) when looking for executable programs, or `load-path'
- (*note Library Search::) when looking for Lisp files. If FILENAME
- is absolute, PATH has no effect, but the suffixes in SUFFIXES are
- still tried.
- The optional argument PREDICATE, if non-`nil', specifies a
- predicate function for testing whether a candidate file is
- suitable. The predicate is passed the candidate file name as its
- single argument. If PREDICATE is `nil' or omitted, `locate-file'
- uses `file-readable-p' as the predicate. *Note Kinds of Files::,
- for other useful predicates, e.g. `file-executable-p' and
- `file-directory-p'.
- For compatibility, PREDICATE can also be one of the symbols
- `executable', `readable', `writable', `exists', or a list of one
- or more of these symbols.
- -- Function: executable-find program
- This function searches for the executable file of the named
- PROGRAM and returns the absolute file name of the executable,
- including its file-name extensions, if any. It returns `nil' if
- the file is not found. The functions searches in all the
- directories in `exec-path', and tries all the file-name extensions
- in `exec-suffixes' (*note Subprocess Creation::).
- File: elisp, Node: Changing Files, Next: File Names, Prev: Information about Files, Up: Files
- 25.7 Changing File Names and Attributes
- =======================================
- The functions in this section rename, copy, delete, link, and set the
- modes (permissions) of files.
- In the functions that have an argument NEWNAME, if a file by the
- name of NEWNAME already exists, the actions taken depend on the value
- of the argument OK-IF-ALREADY-EXISTS:
- * Signal a `file-already-exists' error if OK-IF-ALREADY-EXISTS is
- `nil'.
- * Request confirmation if OK-IF-ALREADY-EXISTS is a number.
- * Replace the old file without confirmation if OK-IF-ALREADY-EXISTS
- is any other value.
- The next four commands all recursively follow symbolic links at all
- levels of parent directories for their first argument, but, if that
- argument is itself a symbolic link, then only `copy-file' replaces it
- with its (recursive) target.
- -- Command: add-name-to-file oldname newname &optional
- ok-if-already-exists
- This function gives the file named OLDNAME the additional name
- NEWNAME. This means that NEWNAME becomes a new "hard link" to
- OLDNAME.
- In the first part of the following example, we list two files,
- `foo' and `foo3'.
- % ls -li fo*
- 81908 -rw-rw-rw- 1 rms 29 Aug 18 20:32 foo
- 84302 -rw-rw-rw- 1 rms 24 Aug 18 20:31 foo3
- Now we create a hard link, by calling `add-name-to-file', then list
- the files again. This shows two names for one file, `foo' and
- `foo2'.
- (add-name-to-file "foo" "foo2")
- => nil
- % ls -li fo*
- 81908 -rw-rw-rw- 2 rms 29 Aug 18 20:32 foo
- 81908 -rw-rw-rw- 2 rms 29 Aug 18 20:32 foo2
- 84302 -rw-rw-rw- 1 rms 24 Aug 18 20:31 foo3
- Finally, we evaluate the following:
- (add-name-to-file "foo" "foo3" t)
- and list the files again. Now there are three names for one file:
- `foo', `foo2', and `foo3'. The old contents of `foo3' are lost.
- (add-name-to-file "foo1" "foo3")
- => nil
- % ls -li fo*
- 81908 -rw-rw-rw- 3 rms 29 Aug 18 20:32 foo
- 81908 -rw-rw-rw- 3 rms 29 Aug 18 20:32 foo2
- 81908 -rw-rw-rw- 3 rms 29 Aug 18 20:32 foo3
- This function is meaningless on operating systems where multiple
- names for one file are not allowed. Some systems implement
- multiple names by copying the file instead.
- See also `file-nlinks' in *note File Attributes::.
- -- Command: rename-file filename newname &optional ok-if-already-exists
- This command renames the file FILENAME as NEWNAME.
- If FILENAME has additional names aside from FILENAME, it continues
- to have those names. In fact, adding the name NEWNAME with
- `add-name-to-file' and then deleting FILENAME has the same effect
- as renaming, aside from momentary intermediate states.
- -- Command: copy-file oldname newname &optional ok-if-exists time
- preserve-uid-gid preserve-selinux
- This command copies the file OLDNAME to NEWNAME. An error is
- signaled if OLDNAME does not exist. If NEWNAME names a directory,
- it copies OLDNAME into that directory, preserving its final name
- component.
- If TIME is non-`nil', then this function gives the new file the
- same last-modified time that the old one has. (This works on only
- some operating systems.) If setting the time gets an error,
- `copy-file' signals a `file-date-error' error. In an interactive
- call, a prefix argument specifies a non-`nil' value for TIME.
- This function copies the file modes, too.
- If argument PRESERVE-UID-GID is `nil', we let the operating system
- decide the user and group ownership of the new file (this is
- usually set to the user running Emacs). If PRESERVE-UID-GID is
- non-`nil', we attempt to copy the user and group ownership of the
- file. This works only on some operating systems, and only if you
- have the correct permissions to do so.
- If the optional argument PRESERVE-SELINUX is non-`nil', and Emacs
- has been compiled with SELinux support, this function attempts to
- copy the file's SELinux context (*note File Attributes::).
- -- Command: make-symbolic-link filename newname &optional ok-if-exists
- This command makes a symbolic link to FILENAME, named NEWNAME.
- This is like the shell command `ln -s FILENAME NEWNAME'.
- This function is not available on systems that don't support
- symbolic links.
- -- Command: delete-file filename &optional trash
- This command deletes the file FILENAME. If the file has multiple
- names, it continues to exist under the other names. If FILENAME
- is a symbolic link, `delete-file' deletes only the symbolic link
- and not its target (though it does follow symbolic links at all
- levels of parent directories).
- A suitable kind of `file-error' error is signaled if the file does
- not exist, or is not deletable. (On Unix and GNU/Linux, a file is
- deletable if its directory is writable.)
- If the optional argument TRASH is non-`nil' and the variable
- `delete-by-moving-to-trash' is non-`nil', this command moves the
- file into the system Trash instead of deleting it. *Note
- Miscellaneous File Operations: (emacs)Misc File Ops. When called
- interactively, TRASH is `t' if no prefix argument is given, and
- `nil' otherwise.
- See also `delete-directory' in *note Create/Delete Dirs::.
- -- Command: set-file-modes filename mode
- This function sets the "file mode" (or "file permissions") of
- FILENAME to MODE. It recursively follows symbolic links at all
- levels for FILENAME.
- If called non-interactively, MODE must be an integer. Only the
- lowest 12 bits of the integer are used; on most systems, only the
- lowest 9 bits are meaningful. You can use the Lisp construct for
- octal numbers to enter MODE. For example,
- (set-file-modes #o644)
- specifies that the file should be readable and writable for its
- owner, readable for group members, and readable for all other
- users. *Note File Permissions: (coreutils)File Permissions, for a
- description of mode bit specifications.
- Interactively, MODE is read from the minibuffer using
- `read-file-modes' (see below), which lets the user type in either
- an integer or a string representing the permissions symbolically.
- *Note File Attributes::, for the function `file-modes', which
- returns the permissions of a file.
- -- Function: set-default-file-modes mode
- This function sets the default file permissions for new files
- created by Emacs and its subprocesses. Every file created with
- Emacs initially has these permissions, or a subset of them
- (`write-region' will not grant execute permissions even if the
- default file permissions allow execution). On Unix and GNU/Linux,
- the default permissions are given by the bitwise complement of the
- "umask" value.
- The argument MODE should be an integer which specifies the
- permissions, similar to `set-file-modes' above. Only the lowest 9
- bits are meaningful.
- The default file permissions have no effect when you save a
- modified version of an existing file; saving a file preserves its
- existing permissions.
- -- Function: default-file-modes
- This function returns the default file permissions, as an integer.
- -- Function: read-file-modes &optional prompt base-file
- This function reads a set of file mode bits from the minibuffer.
- The first optional argument PROMPT specifies a non-default prompt.
- Second second optional argument BASE-FILE is the name of a file on
- whose permissions to base the mode bits that this function returns,
- if what the user types specifies mode bits relative to permissions
- of an existing file.
- If user input represents an octal number, this function returns
- that number. If it is a complete symbolic specification of mode
- bits, as in `"u=rwx"', the function converts it to the equivalent
- numeric value using `file-modes-symbolic-to-number' and returns the
- result. If the specification is relative, as in `"o+g"', then the
- permissions on which the specification is based are taken from the
- mode bits of BASE-FILE. If BASE-FILE is omitted or `nil', the
- function uses `0' as the base mode bits. The complete and
- relative specifications can be combined, as in
- `"u+r,g+rx,o+r,g-w"'. *Note File Permissions: (coreutils)File
- Permissions, for a description of file mode specifications.
- -- Function: file-modes-symbolic-to-number modes &optional base-modes
- This function converts a symbolic file mode specification in MODES
- into the equivalent integer value. If the symbolic specification
- is based on an existing file, that file's mode bits are taken from
- the optional argument BASE-MODES; if that argument is omitted or
- `nil', it defaults to 0, i.e. no access rights at all.
- -- Function: set-file-times filename &optional time
- This function sets the access and modification times of FILENAME
- to TIME. The return value is `t' if the times are successfully
- set, otherwise it is `nil'. TIME defaults to the current time and
- must be in the format returned by `current-time' (*note Time of
- Day::).
- -- Function: set-file-selinux-context filename context
- This function sets the SELinux security context of the file
- FILENAME to CONTEXT. *Note File Attributes::, for a brief
- description of SELinux contexts. The CONTEXT argument should be a
- list `(USER ROLE TYPE RANGE)', like the return value of
- `file-selinux-context'. The function does nothing if SELinux is
- disabled, or if Emacs was compiled without SELinux support.
- File: elisp, Node: File Names, Next: Contents of Directories, Prev: Changing Files, Up: Files
- 25.8 File Names
- ===============
- Files are generally referred to by their names, in Emacs as elsewhere.
- File names in Emacs are represented as strings. The functions that
- operate on a file all expect a file name argument.
- In addition to operating on files themselves, Emacs Lisp programs
- often need to operate on file names; i.e., to take them apart and to use
- part of a name to construct related file names. This section describes
- how to manipulate file names.
- The functions in this section do not actually access files, so they
- can operate on file names that do not refer to an existing file or
- directory.
- On MS-DOS and MS-Windows, these functions (like the function that
- actually operate on files) accept MS-DOS or MS-Windows file-name syntax,
- where backslashes separate the components, as well as Unix syntax; but
- they always return Unix syntax. This enables Lisp programs to specify
- file names in Unix syntax and work properly on all systems without
- change.
- * Menu:
- * File Name Components:: The directory part of a file name, and the rest.
- * Relative File Names:: Some file names are relative to a current directory.
- * Directory Names:: A directory's name as a directory
- is different from its name as a file.
- * File Name Expansion:: Converting relative file names to absolute ones.
- * Unique File Names:: Generating names for temporary files.
- * File Name Completion:: Finding the completions for a given file name.
- * Standard File Names:: If your package uses a fixed file name,
- how to handle various operating systems simply.
- File: elisp, Node: File Name Components, Next: Relative File Names, Up: File Names
- 25.8.1 File Name Components
- ---------------------------
- The operating system groups files into directories. To specify a file,
- you must specify the directory and the file's name within that
- directory. Therefore, Emacs considers a file name as having two main
- parts: the "directory name" part, and the "nondirectory" part (or "file
- name within the directory"). Either part may be empty. Concatenating
- these two parts reproduces the original file name.
- On most systems, the directory part is everything up to and including
- the last slash (backslash is also allowed in input on MS-DOS or
- MS-Windows); the nondirectory part is the rest.
- For some purposes, the nondirectory part is further subdivided into
- the name proper and the "version number". On most systems, only backup
- files have version numbers in their names.
- -- Function: file-name-directory filename
- This function returns the directory part of FILENAME, as a
- directory name (*note Directory Names::), or `nil' if FILENAME
- does not include a directory part.
- On GNU and Unix systems, a string returned by this function always
- ends in a slash. On MS-DOS it can also end in a colon.
- (file-name-directory "lewis/foo") ; Unix example
- => "lewis/"
- (file-name-directory "foo") ; Unix example
- => nil
- -- Function: file-name-nondirectory filename
- This function returns the nondirectory part of FILENAME.
- (file-name-nondirectory "lewis/foo")
- => "foo"
- (file-name-nondirectory "foo")
- => "foo"
- (file-name-nondirectory "lewis/")
- => ""
- -- Function: file-name-sans-versions filename &optional
- keep-backup-version
- This function returns FILENAME with any file version numbers,
- backup version numbers, or trailing tildes discarded.
- If KEEP-BACKUP-VERSION is non-`nil', then true file version
- numbers understood as such by the file system are discarded from
- the return value, but backup version numbers are kept.
- (file-name-sans-versions "~rms/foo.~1~")
- => "~rms/foo"
- (file-name-sans-versions "~rms/foo~")
- => "~rms/foo"
- (file-name-sans-versions "~rms/foo")
- => "~rms/foo"
- -- Function: file-name-extension filename &optional period
- This function returns FILENAME's final "extension", if any, after
- applying `file-name-sans-versions' to remove any version/backup
- part. The extension, in a file name, is the part that follows the
- last `.' in the last name component (minus any version/backup
- part).
- This function returns `nil' for extensionless file names such as
- `foo'. It returns `""' for null extensions, as in `foo.'. If the
- last component of a file name begins with a `.', that `.' doesn't
- count as the beginning of an extension. Thus, `.emacs''s
- "extension" is `nil', not `.emacs'.
- If PERIOD is non-`nil', then the returned value includes the
- period that delimits the extension, and if FILENAME has no
- extension, the value is `""'.
- -- Function: file-name-sans-extension filename
- This function returns FILENAME minus its extension, if any. The
- version/backup part, if present, is only removed if the file has an
- extension. For example,
- (file-name-sans-extension "foo.lose.c")
- => "foo.lose"
- (file-name-sans-extension "big.hack/foo")
- => "big.hack/foo"
- (file-name-sans-extension "/my/home/.emacs")
- => "/my/home/.emacs"
- (file-name-sans-extension "/my/home/.emacs.el")
- => "/my/home/.emacs"
- (file-name-sans-extension "~/foo.el.~3~")
- => "~/foo"
- (file-name-sans-extension "~/foo.~3~")
- => "~/foo.~3~"
- Note that the `.~3~' in the two last examples is the backup part,
- not an extension.
- File: elisp, Node: Relative File Names, Next: Directory Names, Prev: File Name Components, Up: File Names
- 25.8.2 Absolute and Relative File Names
- ---------------------------------------
- All the directories in the file system form a tree starting at the root
- directory. A file name can specify all the directory names starting
- from the root of the tree; then it is called an "absolute" file name.
- Or it can specify the position of the file in the tree relative to a
- default directory; then it is called a "relative" file name. On Unix
- and GNU/Linux, an absolute file name starts with a `/' or a `~' (*note
- abbreviate-file-name::), and a relative one does not. On MS-DOS and
- MS-Windows, an absolute file name starts with a slash or a backslash,
- or with a drive specification `X:/', where X is the "drive letter".
- -- Function: file-name-absolute-p filename
- This function returns `t' if file FILENAME is an absolute file
- name, `nil' otherwise.
- (file-name-absolute-p "~rms/foo")
- => t
- (file-name-absolute-p "rms/foo")
- => nil
- (file-name-absolute-p "/user/rms/foo")
- => t
- Given a possibly relative file name, you can convert it to an
- absolute name using `expand-file-name' (*note File Name Expansion::).
- This function converts absolute file names to relative names:
- -- Function: file-relative-name filename &optional directory
- This function tries to return a relative name that is equivalent to
- FILENAME, assuming the result will be interpreted relative to
- DIRECTORY (an absolute directory name or directory file name). If
- DIRECTORY is omitted or `nil', it defaults to the current buffer's
- default directory.
- On some operating systems, an absolute file name begins with a
- device name. On such systems, FILENAME has no relative equivalent
- based on DIRECTORY if they start with two different device names.
- In this case, `file-relative-name' returns FILENAME in absolute
- form.
- (file-relative-name "/foo/bar" "/foo/")
- => "bar"
- (file-relative-name "/foo/bar" "/hack/")
- => "../foo/bar"
- File: elisp, Node: Directory Names, Next: File Name Expansion, Prev: Relative File Names, Up: File Names
- 25.8.3 Directory Names
- ----------------------
- A "directory name" is the name of a directory. A directory is actually
- a kind of file, so it has a file name, which is related to the
- directory name but not identical to it. (This is not quite the same as
- the usual Unix terminology.) These two different names for the same
- entity are related by a syntactic transformation. On GNU and Unix
- systems, this is simple: a directory name ends in a slash, whereas the
- directory's name as a file lacks that slash. On MS-DOS the
- relationship is more complicated.
- The difference between a directory name and its name as a file is
- subtle but crucial. When an Emacs variable or function argument is
- described as being a directory name, a file name of a directory is not
- acceptable. When `file-name-directory' returns a string, that is
- always a directory name.
- The following two functions convert between directory names and file
- names. They do nothing special with environment variable substitutions
- such as `$HOME', and the constructs `~', `.' and `..'.
- -- Function: file-name-as-directory filename
- This function returns a string representing FILENAME in a form
- that the operating system will interpret as the name of a
- directory. On most systems, this means appending a slash to the
- string (if it does not already end in one).
- (file-name-as-directory "~rms/lewis")
- => "~rms/lewis/"
- -- Function: directory-file-name dirname
- This function returns a string representing DIRNAME in a form that
- the operating system will interpret as the name of a file. On most
- systems, this means removing the final slash (or backslash) from
- the string.
- (directory-file-name "~lewis/")
- => "~lewis"
- Given a directory name, you can combine it with a relative file name
- using `concat':
- (concat DIRNAME RELFILE)
- Be sure to verify that the file name is relative before doing that. If
- you use an absolute file name, the results could be syntactically
- invalid or refer to the wrong file.
- If you want to use a directory file name in making such a
- combination, you must first convert it to a directory name using
- `file-name-as-directory':
- (concat (file-name-as-directory DIRFILE) RELFILE)
- Don't try concatenating a slash by hand, as in
- ;;; Wrong!
- (concat DIRFILE "/" RELFILE)
- because this is not portable. Always use `file-name-as-directory'.
- To convert a directory name to its abbreviation, use this function:
- -- Function: abbreviate-file-name filename
- This function returns an abbreviated form of FILENAME. It applies
- the abbreviations specified in `directory-abbrev-alist' (*note
- File Aliases: (emacs)File Aliases.), then substitutes `~' for the
- user's home directory if the argument names a file in the home
- directory or one of its subdirectories. If the home directory is
- a root directory, it is not replaced with `~', because this does
- not make the result shorter on many systems.
- You can use this function for directory names and for file names,
- because it recognizes abbreviations even as part of the name.
- File: elisp, Node: File Name Expansion, Next: Unique File Names, Prev: Directory Names, Up: File Names
- 25.8.4 Functions that Expand Filenames
- --------------------------------------
- "Expanding" a file name means converting a relative file name to an
- absolute one. Since this is done relative to a default directory, you
- must specify the default directory name as well as the file name to be
- expanded. It also involves expanding abbreviations like `~/' (*note
- abbreviate-file-name::), and eliminating redundancies like `./' and
- `NAME/../'.
- -- Function: expand-file-name filename &optional directory
- This function converts FILENAME to an absolute file name. If
- DIRECTORY is supplied, it is the default directory to start with
- if FILENAME is relative. (The value of DIRECTORY should itself be
- an absolute directory name or directory file name; it may start
- with `~'.) Otherwise, the current buffer's value of
- `default-directory' is used. For example:
- (expand-file-name "foo")
- => "/xcssun/users/rms/lewis/foo"
- (expand-file-name "../foo")
- => "/xcssun/users/rms/foo"
- (expand-file-name "foo" "/usr/spool/")
- => "/usr/spool/foo"
- (expand-file-name "$HOME/foo")
- => "/xcssun/users/rms/lewis/$HOME/foo"
- If the part of the combined file name before the first slash is
- `~', it expands to the value of the `HOME' environment variable
- (usually your home directory). If the part before the first slash
- is `~USER' and if USER is a valid login name, it expands to USER's
- home directory.
- Filenames containing `.' or `..' are simplified to their canonical
- form:
- (expand-file-name "bar/../foo")
- => "/xcssun/users/rms/lewis/foo"
- In some cases, a leading `..' component can remain in the output:
- (expand-file-name "../home" "/")
- => "/../home"
- This is for the sake of filesystems that have the concept of a
- "superroot" above the root directory `/'. On other filesystems,
- `/../' is interpreted exactly the same as `/'.
- Note that `expand-file-name' does _not_ expand environment
- variables; only `substitute-in-file-name' does that.
- Note also that `expand-file-name' does not follow symbolic links
- at any level. This results in a difference between the way
- `file-truename' and `expand-file-name' treat `..'. Assuming that
- `/tmp/bar' is a symbolic link to the directory `/tmp/foo/bar' we
- get:
- (file-truename "/tmp/bar/../myfile")
- => "/tmp/foo/myfile"
- (expand-file-name "/tmp/bar/../myfile")
- => "/tmp/myfile"
- If you may need to follow symbolic links preceding `..', you
- should make sure to call `file-truename' without prior direct or
- indirect calls to `expand-file-name'. *Note Truenames::.
- -- Variable: default-directory
- The value of this buffer-local variable is the default directory
- for the current buffer. It should be an absolute directory name;
- it may start with `~'. This variable is buffer-local in every
- buffer.
- `expand-file-name' uses the default directory when its second
- argument is `nil'.
- The value is always a string ending with a slash.
- default-directory
- => "/user/lewis/manual/"
- -- Function: substitute-in-file-name filename
- This function replaces environment variable references in FILENAME
- with the environment variable values. Following standard Unix
- shell syntax, `$' is the prefix to substitute an environment
- variable value. If the input contains `$$', that is converted to
- `$'; this gives the user a way to "quote" a `$'.
- The environment variable name is the series of alphanumeric
- characters (including underscores) that follow the `$'. If the
- character following the `$' is a `{', then the variable name is
- everything up to the matching `}'.
- Calling `substitute-in-file-name' on output produced by
- `substitute-in-file-name' tends to give incorrect results. For
- instance, use of `$$' to quote a single `$' won't work properly,
- and `$' in an environment variable's value could lead to repeated
- substitution. Therefore, programs that call this function and put
- the output where it will be passed to this function need to double
- all `$' characters to prevent subsequent incorrect results.
- Here we assume that the environment variable `HOME', which holds
- the user's home directory name, has value `/xcssun/users/rms'.
- (substitute-in-file-name "$HOME/foo")
- => "/xcssun/users/rms/foo"
- After substitution, if a `~' or a `/' appears immediately after
- another `/', the function discards everything before it (up
- through the immediately preceding `/').
- (substitute-in-file-name "bar/~/foo")
- => "~/foo"
- (substitute-in-file-name "/usr/local/$HOME/foo")
- => "/xcssun/users/rms/foo"
- ;; `/usr/local/' has been discarded.
- File: elisp, Node: Unique File Names, Next: File Name Completion, Prev: File Name Expansion, Up: File Names
- 25.8.5 Generating Unique File Names
- -----------------------------------
- Some programs need to write temporary files. Here is the usual way to
- construct a name for such a file:
- (make-temp-file NAME-OF-APPLICATION)
- The job of `make-temp-file' is to prevent two different users or two
- different jobs from trying to use the exact same file name.
- -- Function: make-temp-file prefix &optional dir-flag suffix
- This function creates a temporary file and returns its name. Emacs
- creates the temporary file's name by adding to PREFIX some random
- characters that are different in each Emacs job. The result is
- guaranteed to be a newly created empty file. On MS-DOS, this
- function can truncate the STRING prefix to fit into the 8+3
- file-name limits. If PREFIX is a relative file name, it is
- expanded against `temporary-file-directory'.
- (make-temp-file "foo")
- => "/tmp/foo232J6v"
- When `make-temp-file' returns, the file has been created and is
- empty. At that point, you should write the intended contents into
- the file.
- If DIR-FLAG is non-`nil', `make-temp-file' creates an empty
- directory instead of an empty file. It returns the file name, not
- the directory name, of that directory. *Note Directory Names::.
- If SUFFIX is non-`nil', `make-temp-file' adds it at the end of the
- file name.
- To prevent conflicts among different libraries running in the same
- Emacs, each Lisp program that uses `make-temp-file' should have its
- own PREFIX. The number added to the end of PREFIX distinguishes
- between the same application running in different Emacs jobs.
- Additional added characters permit a large number of distinct
- names even in one Emacs job.
- The default directory for temporary files is controlled by the
- variable `temporary-file-directory'. This variable gives the user a
- uniform way to specify the directory for all temporary files. Some
- programs use `small-temporary-file-directory' instead, if that is
- non-`nil'. To use it, you should expand the prefix against the proper
- directory before calling `make-temp-file'.
- -- User Option: temporary-file-directory
- This variable specifies the directory name for creating temporary
- files. Its value should be a directory name (*note Directory
- Names::), but it is good for Lisp programs to cope if the value is
- a directory's file name instead. Using the value as the second
- argument to `expand-file-name' is a good way to achieve that.
- The default value is determined in a reasonable way for your
- operating system; it is based on the `TMPDIR', `TMP' and `TEMP'
- environment variables, with a fall-back to a system-dependent name
- if none of these variables is defined.
- Even if you do not use `make-temp-file' to create the temporary
- file, you should still use this variable to decide which directory
- to put the file in. However, if you expect the file to be small,
- you should use `small-temporary-file-directory' first if that is
- non-`nil'.
- -- User Option: small-temporary-file-directory
- This variable specifies the directory name for creating certain
- temporary files, which are likely to be small.
- If you want to write a temporary file which is likely to be small,
- you should compute the directory like this:
- (make-temp-file
- (expand-file-name PREFIX
- (or small-temporary-file-directory
- temporary-file-directory)))
- -- Function: make-temp-name base-name
- This function generates a string that can be used as a unique file
- name. The name starts with BASE-NAME, and has several random
- characters appended to it, which are different in each Emacs job.
- It is like `make-temp-file' except that (i) it just constructs a
- name, and does not create a file, and (ii) BASE-NAME should be an
- absolute file name (on MS-DOS, this function can truncate
- BASE-NAME to fit into the 8+3 file-name limits).
- *Warning:* In most cases, you should not use this function; use
- `make-temp-file' instead! This function is susceptible to a race
- condition, between the `make-temp-name' call and the creation of
- the file, which in some cases may cause a security hole.
- File: elisp, Node: File Name Completion, Next: Standard File Names, Prev: Unique File Names, Up: File Names
- 25.8.6 File Name Completion
- ---------------------------
- This section describes low-level subroutines for completing a file
- name. For higher level functions, see *note Reading File Names::.
- -- Function: file-name-all-completions partial-filename directory
- This function returns a list of all possible completions for a file
- whose name starts with PARTIAL-FILENAME in directory DIRECTORY.
- The order of the completions is the order of the files in the
- directory, which is unpredictable and conveys no useful
- information.
- The argument PARTIAL-FILENAME must be a file name containing no
- directory part and no slash (or backslash on some systems). The
- current buffer's default directory is prepended to DIRECTORY, if
- DIRECTORY is not absolute.
- In the following example, suppose that `~rms/lewis' is the current
- default directory, and has five files whose names begin with `f':
- `foo', `file~', `file.c', `file.c.~1~', and `file.c.~2~'.
- (file-name-all-completions "f" "")
- => ("foo" "file~" "file.c.~2~"
- "file.c.~1~" "file.c")
- (file-name-all-completions "fo" "")
- => ("foo")
- -- Function: file-name-completion filename directory &optional
- predicate
- This function completes the file name FILENAME in directory
- DIRECTORY. It returns the longest prefix common to all file names
- in directory DIRECTORY that start with FILENAME. If PREDICATE is
- non-`nil' then it ignores possible completions that don't satisfy
- PREDICATE, after calling that function with one argument, the
- expanded absolute file name.
- If only one match exists and FILENAME matches it exactly, the
- function returns `t'. The function returns `nil' if directory
- DIRECTORY contains no name starting with FILENAME.
- In the following example, suppose that the current default
- directory has five files whose names begin with `f': `foo',
- `file~', `file.c', `file.c.~1~', and `file.c.~2~'.
- (file-name-completion "fi" "")
- => "file"
- (file-name-completion "file.c.~1" "")
- => "file.c.~1~"
- (file-name-completion "file.c.~1~" "")
- => t
- (file-name-completion "file.c.~3" "")
- => nil
- -- User Option: completion-ignored-extensions
- `file-name-completion' usually ignores file names that end in any
- string in this list. It does not ignore them when all the possible
- completions end in one of these suffixes. This variable has no
- effect on `file-name-all-completions'.
- A typical value might look like this:
- completion-ignored-extensions
- => (".o" ".elc" "~" ".dvi")
- If an element of `completion-ignored-extensions' ends in a slash
- `/', it signals a directory. The elements which do _not_ end in a
- slash will never match a directory; thus, the above value will not
- filter out a directory named `foo.elc'.
- File: elisp, Node: Standard File Names, Prev: File Name Completion, Up: File Names
- 25.8.7 Standard File Names
- --------------------------
- Sometimes, an Emacs Lisp program needs to specify a standard file name
- for a particular use--typically, to hold configuration data specified
- by the current user. Usually, such files should be located in the
- directory specified by `user-emacs-directory', which is `~/.emacs.d' by
- default (*note Init File::). For example, abbrev definitions are
- stored by default in `~/.emacs.d/abbrev_defs'. The easiest way to
- specify such a file name is to use the function
- `locate-user-emacs-file'.
- -- Function: locate-user-emacs-file base-name &optional old-name
- This function returns an absolute file name for an Emacs-specific
- configuration or data file. The argument `base-name' should be a
- relative file name. The return value is the absolute name of a
- file in the directory specified by `user-emacs-directory'; if that
- directory does not exist, this function creates it.
- If the optional argument OLD-NAME is non-`nil', it specifies a
- file in the user's home directory, `~/OLD-NAME'. If such a file
- exists, the return value is the absolute name of that file,
- instead of the file specified by BASE-NAME. This argument is
- intended to be used by Emacs packages to provide backward
- compatibility. For instance, prior to the introduction of
- `user-emacs-directory', the abbrev file was located in
- `~/.abbrev_defs'. Here is the definition of `abbrev-file-name':
- (defcustom abbrev-file-name
- (locate-user-emacs-file "abbrev_defs" ".abbrev_defs")
- "Default name of file from which to read abbrevs."
- ...
- :type 'file)
- A lower-level function for standardizing file names, which
- `locate-user-emacs-file' uses as a subroutine, is
- `convert-standard-filename'.
- -- Function: convert-standard-filename filename
- This function returns a file name based on FILENAME, which fits
- the conventions of the current operating system.
- On GNU and Unix systems, this simply returns FILENAME. On other
- operating systems, it may enforce system-specific file name
- conventions; for example, on MS-DOS this function performs a
- variety of changes to enforce MS-DOS file name limitations,
- including converting any leading `.' to `_' and truncating to three
- characters after the `.'.
- The recommended way to use this function is to specify a name which
- fits the conventions of GNU and Unix systems, and pass it to
- `convert-standard-filename'.
- File: elisp, Node: Contents of Directories, Next: Create/Delete Dirs, Prev: File Names, Up: Files
- 25.9 Contents of Directories
- ============================
- A directory is a kind of file that contains other files entered under
- various names. Directories are a feature of the file system.
- Emacs can list the names of the files in a directory as a Lisp list,
- or display the names in a buffer using the `ls' shell command. In the
- latter case, it can optionally display information about each file,
- depending on the options passed to the `ls' command.
- -- Function: directory-files directory &optional full-name
- match-regexp nosort
- This function returns a list of the names of the files in the
- directory DIRECTORY. By default, the list is in alphabetical
- order.
- If FULL-NAME is non-`nil', the function returns the files'
- absolute file names. Otherwise, it returns the names relative to
- the specified directory.
- If MATCH-REGEXP is non-`nil', this function returns only those
- file names that contain a match for that regular expression--the
- other file names are excluded from the list. On case-insensitive
- filesystems, the regular expression matching is case-insensitive.
- If NOSORT is non-`nil', `directory-files' does not sort the list,
- so you get the file names in no particular order. Use this if you
- want the utmost possible speed and don't care what order the files
- are processed in. If the order of processing is visible to the
- user, then the user will probably be happier if you do sort the
- names.
- (directory-files "~lewis")
- => ("#foo#" "#foo.el#" "." ".."
- "dired-mods.el" "files.texi"
- "files.texi.~1~")
- An error is signaled if DIRECTORY is not the name of a directory
- that can be read.
- -- Function: directory-files-and-attributes directory &optional
- full-name match-regexp nosort id-format
- This is similar to `directory-files' in deciding which files to
- report on and how to report their names. However, instead of
- returning a list of file names, it returns for each file a list
- `(FILENAME . ATTRIBUTES)', where ATTRIBUTES is what
- `file-attributes' would return for that file. The optional
- argument ID-FORMAT has the same meaning as the corresponding
- argument to `file-attributes' (*note Definition of
- file-attributes::).
- -- Function: file-expand-wildcards pattern &optional full
- This function expands the wildcard pattern PATTERN, returning a
- list of file names that match it.
- If PATTERN is written as an absolute file name, the values are
- absolute also.
- If PATTERN is written as a relative file name, it is interpreted
- relative to the current default directory. The file names
- returned are normally also relative to the current default
- directory. However, if FULL is non-`nil', they are absolute.
- -- Function: insert-directory file switches &optional wildcard
- full-directory-p
- This function inserts (in the current buffer) a directory listing
- for directory FILE, formatted with `ls' according to SWITCHES. It
- leaves point after the inserted text. SWITCHES may be a string of
- options, or a list of strings representing individual options.
- The argument FILE may be either a directory name or a file
- specification including wildcard characters. If WILDCARD is
- non-`nil', that means treat FILE as a file specification with
- wildcards.
- If FULL-DIRECTORY-P is non-`nil', that means the directory listing
- is expected to show the full contents of a directory. You should
- specify `t' when FILE is a directory and switches do not contain
- `-d'. (The `-d' option to `ls' says to describe a directory
- itself as a file, rather than showing its contents.)
- On most systems, this function works by running a directory listing
- program whose name is in the variable `insert-directory-program'.
- If WILDCARD is non-`nil', it also runs the shell specified by
- `shell-file-name', to expand the wildcards.
- MS-DOS and MS-Windows systems usually lack the standard Unix
- program `ls', so this function emulates the standard Unix program
- `ls' with Lisp code.
- As a technical detail, when SWITCHES contains the long `--dired'
- option, `insert-directory' treats it specially, for the sake of
- dired. However, the normally equivalent short `-D' option is just
- passed on to `insert-directory-program', as any other option.
- -- Variable: insert-directory-program
- This variable's value is the program to run to generate a
- directory listing for the function `insert-directory'. It is
- ignored on systems which generate the listing with Lisp code.
- File: elisp, Node: Create/Delete Dirs, Next: Magic File Names, Prev: Contents of Directories, Up: Files
- 25.10 Creating, Copying and Deleting Directories
- ================================================
- Most Emacs Lisp file-manipulation functions get errors when used on
- files that are directories. For example, you cannot delete a directory
- with `delete-file'. These special functions exist to create and delete
- directories.
- -- Command: make-directory dirname &optional parents
- This command creates a directory named DIRNAME. If PARENTS is
- non-`nil', as is always the case in an interactive call, that
- means to create the parent directories first, if they don't
- already exist.
- `mkdir' is an alias for this.
- -- Command: copy-directory dirname newname &optional keep-time parents
- copy-contents
- This command copies the directory named DIRNAME to NEWNAME. If
- NEWNAME names an existing directory, DIRNAME will be copied to a
- subdirectory there.
- It always sets the file modes of the copied files to match the
- corresponding original file.
- The third argument KEEP-TIME non-`nil' means to preserve the
- modification time of the copied files. A prefix arg makes
- KEEP-TIME non-`nil'.
- The fourth argument PARENTS says whether to create parent
- directories if they don't exist. Interactively, this happens by
- default.
- The fifth argument COPY-CONTENTS, if non-`nil', means to copy the
- contents of DIRNAME directly into NEWNAME if the latter is an
- existing directory, instead of copying DIRNAME into it as a
- subdirectory.
- -- Command: delete-directory dirname &optional recursive trash
- This command deletes the directory named DIRNAME. The function
- `delete-file' does not work for files that are directories; you
- must use `delete-directory' for them. If RECURSIVE is `nil', and
- the directory contains any files, `delete-directory' signals an
- error.
- `delete-directory' only follows symbolic links at the level of
- parent directories.
- If the optional argument TRASH is non-`nil' and the variable
- `delete-by-moving-to-trash' is non-`nil', this command moves the
- file into the system Trash instead of deleting it. *Note
- Miscellaneous File Operations: (emacs)Misc File Ops. When called
- interactively, TRASH is `t' if no prefix argument is given, and
- `nil' otherwise.
- File: elisp, Node: Magic File Names, Next: Format Conversion, Prev: Create/Delete Dirs, Up: Files
- 25.11 Making Certain File Names "Magic"
- =======================================
- You can implement special handling for certain file names. This is
- called making those names "magic". The principal use for this feature
- is in implementing remote file names (*note Remote Files: (emacs)Remote
- Files.).
- To define a kind of magic file name, you must supply a regular
- expression to define the class of names (all those that match the
- regular expression), plus a handler that implements all the primitive
- Emacs file operations for file names that match.
- The variable `file-name-handler-alist' holds a list of handlers,
- together with regular expressions that determine when to apply each
- handler. Each element has this form:
- (REGEXP . HANDLER)
- All the Emacs primitives for file access and file name transformation
- check the given file name against `file-name-handler-alist'. If the
- file name matches REGEXP, the primitives handle that file by calling
- HANDLER.
- The first argument given to HANDLER is the name of the primitive, as
- a symbol; the remaining arguments are the arguments that were passed to
- that primitive. (The first of these arguments is most often the file
- name itself.) For example, if you do this:
- (file-exists-p FILENAME)
- and FILENAME has handler HANDLER, then HANDLER is called like this:
- (funcall HANDLER 'file-exists-p FILENAME)
- When a function takes two or more arguments that must be file names,
- it checks each of those names for a handler. For example, if you do
- this:
- (expand-file-name FILENAME DIRNAME)
- then it checks for a handler for FILENAME and then for a handler for
- DIRNAME. In either case, the HANDLER is called like this:
- (funcall HANDLER 'expand-file-name FILENAME DIRNAME)
- The HANDLER then needs to figure out whether to handle FILENAME or
- DIRNAME.
- If the specified file name matches more than one handler, the one
- whose match starts last in the file name gets precedence. This rule is
- chosen so that handlers for jobs such as uncompression are handled
- first, before handlers for jobs such as remote file access.
- Here are the operations that a magic file name handler gets to
- handle:
- `access-file', `add-name-to-file', `byte-compiler-base-file-name',
- `copy-directory', `copy-file', `delete-directory', `delete-file',
- `diff-latest-backup-file', `directory-file-name', `directory-files',
- `directory-files-and-attributes', `dired-compress-file',
- `dired-uncache',
- `expand-file-name', `file-accessible-directory-p', `file-attributes',
- `file-directory-p', `file-executable-p', `file-exists-p',
- `file-local-copy', `file-remote-p', `file-modes',
- `file-name-all-completions', `file-name-as-directory',
- `file-name-completion', `file-name-directory', `file-name-nondirectory',
- `file-name-sans-versions', `file-newer-than-file-p',
- `file-ownership-preserved-p', `file-readable-p', `file-regular-p',
- `file-in-directory-p', `file-symlink-p', `file-truename',
- `file-writable-p', `file-equal-p', `find-backup-file-name',
- `get-file-buffer', `insert-directory', `insert-file-contents',
- `load', `make-auto-save-file-name', `make-directory',
- `make-directory-internal', `make-symbolic-link',
- `process-file', `rename-file', `set-file-modes', `set-file-times',
- `set-visited-file-modtime', `shell-command', `start-file-process',
- `substitute-in-file-name',
- `unhandled-file-name-directory', `vc-registered',
- `verify-visited-file-modtime',
- `write-region'.
- Handlers for `insert-file-contents' typically need to clear the
- buffer's modified flag, with `(set-buffer-modified-p nil)', if the
- VISIT argument is non-`nil'. This also has the effect of unlocking the
- buffer if it is locked.
- The handler function must handle all of the above operations, and
- possibly others to be added in the future. It need not implement all
- these operations itself--when it has nothing special to do for a
- certain operation, it can reinvoke the primitive, to handle the
- operation "in the usual way". It should always reinvoke the primitive
- for an operation it does not recognize. Here's one way to do this:
- (defun my-file-handler (operation &rest args)
- ;; First check for the specific operations
- ;; that we have special handling for.
- (cond ((eq operation 'insert-file-contents) ...)
- ((eq operation 'write-region) ...)
- ...
- ;; Handle any operation we don't know about.
- (t (let ((inhibit-file-name-handlers
- (cons 'my-file-handler
- (and (eq inhibit-file-name-operation operation)
- inhibit-file-name-handlers)))
- (inhibit-file-name-operation operation))
- (apply operation args)))))
- When a handler function decides to call the ordinary Emacs primitive
- for the operation at hand, it needs to prevent the primitive from
- calling the same handler once again, thus leading to an infinite
- recursion. The example above shows how to do this, with the variables
- `inhibit-file-name-handlers' and `inhibit-file-name-operation'. Be
- careful to use them exactly as shown above; the details are crucial for
- proper behavior in the case of multiple handlers, and for operations
- that have two file names that may each have handlers.
- Handlers that don't really do anything special for actual access to
- the file--such as the ones that implement completion of host names for
- remote file names--should have a non-`nil' `safe-magic' property. For
- instance, Emacs normally "protects" directory names it finds in `PATH'
- from becoming magic, if they look like magic file names, by prefixing
- them with `/:'. But if the handler that would be used for them has a
- non-`nil' `safe-magic' property, the `/:' is not added.
- A file name handler can have an `operations' property to declare
- which operations it handles in a nontrivial way. If this property has
- a non-`nil' value, it should be a list of operations; then only those
- operations will call the handler. This avoids inefficiency, but its
- main purpose is for autoloaded handler functions, so that they won't be
- loaded except when they have real work to do.
- Simply deferring all operations to the usual primitives does not
- work. For instance, if the file name handler applies to
- `file-exists-p', then it must handle `load' itself, because the usual
- `load' code won't work properly in that case. However, if the handler
- uses the `operations' property to say it doesn't handle
- `file-exists-p', then it need not handle `load' nontrivially.
- -- Variable: inhibit-file-name-handlers
- This variable holds a list of handlers whose use is presently
- inhibited for a certain operation.
- -- Variable: inhibit-file-name-operation
- The operation for which certain handlers are presently inhibited.
- -- Function: find-file-name-handler file operation
- This function returns the handler function for file name FILE, or
- `nil' if there is none. The argument OPERATION should be the
- operation to be performed on the file--the value you will pass to
- the handler as its first argument when you call it. If OPERATION
- equals `inhibit-file-name-operation', or if it is not found in the
- `operations' property of the handler, this function returns `nil'.
- -- Function: file-local-copy filename
- This function copies file FILENAME to an ordinary non-magic file
- on the local machine, if it isn't on the local machine already.
- Magic file names should handle the `file-local-copy' operation if
- they refer to files on other machines. A magic file name that is
- used for other purposes than remote file access should not handle
- `file-local-copy'; then this function will treat the file as local.
- If FILENAME is local, whether magic or not, this function does
- nothing and returns `nil'. Otherwise it returns the file name of
- the local copy file.
- -- Function: file-remote-p filename &optional identification connected
- This function tests whether FILENAME is a remote file. If
- FILENAME is local (not remote), the return value is `nil'. If
- FILENAME is indeed remote, the return value is a string that
- identifies the remote system.
- This identifier string can include a host name and a user name, as
- well as characters designating the method used to access the remote
- system. For example, the remote identifier string for the filename
- `/sudo::/some/file' is `/sudo:root@localhost:'.
- If `file-remote-p' returns the same identifier for two different
- filenames, that means they are stored on the same file system and
- can be accessed locally with respect to each other. This means,
- for example, that it is possible to start a remote process
- accessing both files at the same time. Implementers of file
- handlers need to ensure this principle is valid.
- IDENTIFICATION specifies which part of the identifier shall be
- returned as string. IDENTIFICATION can be the symbol `method',
- `user' or `host'; any other value is handled like `nil' and means
- to return the complete identifier string. In the example above,
- the remote `user' identifier string would be `root'.
- If CONNECTED is non-`nil', this function returns `nil' even if
- FILENAME is remote, if Emacs has no network connection to its
- host. This is useful when you want to avoid the delay of making
- connections when they don't exist.
- -- Function: unhandled-file-name-directory filename
- This function returns the name of a directory that is not magic.
- It uses the directory part of FILENAME if that is not magic. For a
- magic file name, it invokes the file name handler, which therefore
- decides what value to return. If FILENAME is not accessible from
- a local process, then the file name handler should indicate it by
- returning `nil'.
- This is useful for running a subprocess; every subprocess must
- have a non-magic directory to serve as its current directory, and
- this function is a good way to come up with one.
- -- User Option: remote-file-name-inhibit-cache
- The attributes of remote files can be cached for better
- performance. If they are changed outside of Emacs's control, the
- cached values become invalid, and must be reread.
- When this variable is set to `nil', cached values are never
- expired. Use this setting with caution, only if you are sure
- nothing other than Emacs ever changes the remote files. If it is
- set to `t', cached values are never used. This is the safest
- value, but could result in performance degradation.
- A compromise is to set it to a positive number. This means that
- cached values are used for that amount of seconds since they were
- cached. If a remote file is checked regularly, it might be a good
- idea to let-bind this variable to a value less than the time period
- between consecutive checks. For example:
- (defun display-time-file-nonempty-p (file)
- (let ((remote-file-name-inhibit-cache
- (- display-time-interval 5)))
- (and (file-exists-p file)
- (< 0 (nth 7 (file-attributes
- (file-chase-links file)))))))
- File: elisp, Node: Format Conversion, Prev: Magic File Names, Up: Files
- 25.12 File Format Conversion
- ============================
- Emacs performs several steps to convert the data in a buffer (text,
- text properties, and possibly other information) to and from a
- representation suitable for storing into a file. This section describes
- the fundamental functions that perform this "format conversion", namely
- `insert-file-contents' for reading a file into a buffer, and
- `write-region' for writing a buffer into a file.
- * Menu:
- * Overview: Format Conversion Overview. `insert-file-contents' and `write-region'.
- * Round-Trip: Format Conversion Round-Trip. Using `format-alist'.
- * Piecemeal: Format Conversion Piecemeal. Specifying non-paired conversion.
- File: elisp, Node: Format Conversion Overview, Next: Format Conversion Round-Trip, Up: Format Conversion
- 25.12.1 Overview
- ----------------
- The function `insert-file-contents':
- * initially, inserts bytes from the file into the buffer;
- * decodes bytes to characters as appropriate;
- * processes formats as defined by entries in `format-alist'; and
- * calls functions in `after-insert-file-functions'.
- The function `write-region':
- * initially, calls functions in `write-region-annotate-functions';
- * processes formats as defined by entries in `format-alist';
- * encodes characters to bytes as appropriate; and
- * modifies the file with the bytes.
- This shows the symmetry of the lowest-level operations; reading and
- writing handle things in opposite order. The rest of this section
- describes the two facilities surrounding the three variables named
- above, as well as some related functions. *note Coding Systems::, for
- details on character encoding and decoding.
- Local Variables:
- coding: iso-8859-1
- End:
|