; TeX output 1991.05.01:13593ڍ㍑uPDJNj cmbx12JGNUƧReadlineLibrary#$2K`y 3 cmr10BrianfFeo!xgFereefSoft!wareFeoundation^Veersionf1.1ĽAprilf1991*3ڍЍThisdoMcumen!tdescribestheGNUReadlineLibrarye,autilit!yforaidingintheconsistencyofuserin!terfacefacrossdiscreteprogramsthatneedtoprovideacommandlineinterface.!Publishedfb!ytheFereeSoftwareFeoundation675fMassac!husettsAvenue,Cam!bridge,fMA02139USAP!ermissionisgrantedtomakeanddistributeverbatimcopiesofthismanualprovidedthecopyrightnoticefandthispMermissionnoticearepreserv!edonallcopies.P!ermission\isgrantedtocopyanddistributemoMdi edversionsofthismanualundertheconditionsforv!erbatimcopying,!providedthattheentireresultingderivedworkisdistributedunderthetermsoffapMermissionnoticeiden!ticaltothisone.P!ermissionisgrantedtocopyanddistributetranslationsofthismanualintoanotherlanguage,under`ltheabMo!ve`lconditionsformodi edv!ersions,nkexceptthatthispermissionnoticema!ybestatedinfatranslationappro!vedfbytheFeoundation.7 Cop!yright7xcf !", cmsy10 L1989,f1991FereeSoft!warefFoundation,Inc.5Chapterf1:CommandLineEditing'o13ڍЍ;NG cmbx121 QCommandzLineEditing6%ThisftextdescribMesGNU'scommandlineeditingin!terface.Fwy@Nff cmbx12@1.1Intros3ductionfftoLineEditing"cInfthistexathefollo!wingnotationisusedtodescribMekeystrokes.The] text3)9Mo!veftotheendoftheinputhistorye,i.e.,theliney!ouareentering!reverse-search-historyf(C-r)9Searc!h<@backwardstartingatthecurrentlineandmoving`up'throughthehistoryas9necessarye.Thisfisanincremen!talsearch.forward-search-historyf(C-s)9Searc!h}-forwardstartingatthecurrentlineandmoving`down'throughthethehistory9asfneccessarye.4 E1.3.1.3d(CommandspFģorChangingText!Mdelete-charf(C-d)9Deletethec!haracterunderthecursor.IfthecursorisatthebMeginningoftheline,9andftherearenoc!haractersintheline,randthelastcharactertypMedwasnotC-d,rthen9returnfEOF.backward-delete-charf(Rubout)9Deletethec!haracterbMehindthecursor.NAwnumericargsaystokillthecharactersinstead9offdeletingthem.quoted-insertf(C-q,C-v)9Add"thenextc!haracterthatyoutypMetothelineverbatim. Thisishowtoinsertthings9lik!efC-qforexample.tab-insertf(M-TAB)9Insertfatabc!haracter.self-insertf(a,b,A,1,!,...)9Insertfy!ourself.transpose-charsf(C-t)9Drag2thec!haracterbMeforepoin!tforwardoverthecharacteratpMoint. 2Pointmoves9forw!ardC~aswell.$IfpMointisattheendoftheline,jthentranspMosethetwocharacters9bMeforefpoin!t.Negativeargsdon'twork.transpose-wordsf(M-t)9Dragthew!ordbMehindthecursorpastthewordinfrontofthecursormovingthecursor9o!verfthatw!ordaswell.upcase-wordf(M-u)9UppMercaseFthecurren!t(orfollowing)word.Withanegativeargument,YIdotheprevious9w!ord,fbutdonotmovepMoint.2Chapterf1:CommandLineEditing'o73ڍЍdowncase-wordf(M-l)9Lo!wercase^}thecurren!t(orfollowing)word.Withanegativeargument,ldotheprevious9w!ord,fbutdonotmovepMoint..capitalize-wordf(M-c)9UppMercaseFthecurren!t(orfollowing)word.Withanegativeargument,YIdotheprevious9w!ord,fbutdonotmovepMoint..HE1.3.1.4d(KillingpAndYģanking!kill-linef(C-k)9Killfthetextfromthecurren!tcursorpMositiontotheendoftheline.backward-kill-linef()9Killfbac!kwardtothebMeginningoftheline.ThisisnormallyunbMound.kill-wordf(M-d)9Killfromthecursortotheendofthecurren!tword,orifbMetweenwords,totheendof9thefnextw!ord.backward-kill-wordf(M-DEL)9Killfthew!ordbMehindthecursor.unix-line-discardf(C-u)9Do3 whatC-uusedtodoinUnixlineinput.Weesa!ve3 thekilledtextonthekill-ring,9though.unix-word-ruboutf(C-w)9Do whatC-wusedtodoinUnixlineinput.Thekilledtextissa!ved onthekill-ring.9Thisfisdi eren!tthanbackward-kill-wordbMecausethewordbMoundariesdi er.yankf(C-y)9Yeankfthetopofthekillringin!tothebu eratpMoint.yank-popf(M-y)9RotatePthekill-ring,aandy!ankthenewtop.@Yeoucanonlydothisifthepriorcommand9isfy!ankoryank-pMop..HE1.3.1.5d(SpiecifyingpNumericArguments!digit-argumentf(M-0,M-1,...M--)9Add[>thisdigittotheargumen!talreadyaccumulating,torstartanewargument.eM{9startsfanegativ!eargument.universal-argumentf()9DofwhatC-udoMesinemacs.Bydefault,thisisnotbound.;,8bGNUfReadlineLibrary3ڍЍE1.3.1.6d(LettingpReadlineTypieFģorYou!%completef(TAB)9A!ttemptL>todocompletiononthetextbMeforepoin!t.eThisisimplementationde ned.9Generallye,`if;Hy!ouaretypinga lenameargument,`youcando lenamecompletion;if9y!ouVaretypingacommand,youcandocommandcompletion,ifyouaretypingina9sym!bMoltoGDB,youcandosymbMolnamecompletion,EifyouaretypinginavdDariable9tofBash,y!oucandovdDariablenamecompletion...%possible-completionsf(M-?)9ListfthepMossiblecompletionsofthetextbeforepoin!t.3NE1.3.1.7d(SomepMiscellaneousCommandsabortf(C-g)9Ding!Stopsfthings.%do-uppercase-versionf(M-a,M-b,...)9RunfthecommandthatisbMoundtoy!ouruppercasebrother.prefix-metaf(ESC)9Mak!e~KthenextcharacterthatyoutypMebemeta ed.Thisisforpeoplewithoutameta9k!eye.ESC-FfisequivdDalenttoM-F.undof(C-_)9Incremen!talfundo,separatelyremembMeredforeachline.revert-linef(M-r)9Undo\allc!hangesmadetothisline.Thisisliketypingthe`undo'commandenough9timesftogetbac!ktothebMeginning.3NE1.3.2d(ReadlinepViMoide!%WhileCtheReadlinelibrarydoMesnotha!veCafullsetofVieditingfunctions,Jitdoescon!tainenoughtofallo!wsimpleeditingoftheline.Inordertoswitc!hinteractivelybMetweenEmacsandVieditingmoMdes,usethecommandM-C-j(toggle-editing-moMde).Whenmjy!ouenteralineinVimoMde,+youarealreadyplacedin`insertion'moMde,+asifyouhadt!ypMed9Ian`i'.PressingESCswitchesyouinto`edit'moMde,^whereyoucaneditthetextoftheline C4Chapterf1:CommandLineEditing'o93ڍЍwithcthestandardVimo!vementckeys,)movetoprevioushistorylineswith`k',)andfollowinglineswithf`j',andsoforth. Kf10]+GNUfReadlineLibrary3ڟ LqChapterf2:ProgrammingwithGNUReadline113ڍЍ2 QProgrammingzwithGNUReadline-ipThisРman!ualdescribMestheinterfacebMetweentheGNUЕReadlineLibraryanduserprograms.\Ify!ouareaprogrammer,jandyouwishtoincludethefeaturesfoundinGNUReadlineinyourownprograms, suc!hRascompletion,lineediting,andin!teractiveRhistorymanipulation,thisdoMcumen!ta-tionfisfory!ou.6ʍ@2.1DefaultffBehaviour!Man!yprogramsprovideacommandlineinterface,˴suchasmail,˴ftp,andsh.Feorsuchprograms,thedefaultbMeha!viourofReadlineissucient.@^ThissectiondescribMeshowtouseReadlineinthesimplestfw!aypMossible,perhapstoreplacecallsiny!ourcodetogets().The,)functionreadlineprin!tsapromptandthenreadsandreturnsasinglelineoftextfromtheDuser.TThelinewhic!hreadlinef()returnsisalloMcatedwithmalloc();eTy!oushouldfree()thelinefwheny!ouaredonewithit.ThedeclarationforreadlineinANSICisUchar*readline(char*prompt=);So,fonemigh!tsayUchar*line=readline("Enteraline:");infordertoreadalineoftextfromtheuser.Theflinewhic!hisreturnedhasthe nalnewlineremoved,soonlythetextofthelineremains.Iforeadlineencoun!tersanEOFwhilereadingtheline,qandthelineisemptyatthatpMoint,qthen(charf*)NULLisreturned.Otherwise,thelineisendedjustasifanewlinew!astypMed.Ify!ouwanttheusertobMeabletogetatthelinelater,)(withC-Pforexample),y!oumustcalladd_historyf()tosa!vefthelinea!wayfinahistory~listofsuc!hlines.Uadd_history(line);FeorffulldetailsontheGNUHistoryLibrary,seetheassoMciatedman!ual. Lэ12]+GNUfReadlineLibrary3ڍЍItispMolitetoa!voidsavingemptylinesonthehistorylist,8sinceitisrarethansomeonehasaburning~needtoreuseablankline.@&Hereisafunctionwhic!husefullyreplacesthestandardgets()flibraryfunction:$WݍU/*Astaticvariableforholdingtheline.*/ Ustaticchar*line_read=(char*)NULL;U/*Readastring,andreturnapointertoit. TReturnsNULLonEOF.*/Uchar*Udo_gets()U{(g/*Ifthebufferhasalreadybeenallocated,returnthememory9tothefreepool.*/(gif(line_read!=(char*)NULL)3{?fQfree(line_read);?fQline_read=(char*)NULL;3}(g/*Getalinefromtheuser.*/(gline_read=readline("");(g/*Ifthelinehasanytextinit,saveitonthehistory.*/(gif(line_read&&*line_read)3add_history(line_read);(greturn(line_read);U}$WݍThe abMo!vecoMdegivestheuserthedefaultbMehaviourofTABcompletion:%completionon lenames.HIfWy!oudonotwantreadlinetocompleteon lenames,=youcanchangethebindingoftheTABfk!eywithrl_bind_key().Uintrl_bind_key(intk!ey,(int(*)())function);rl_bind_keyf()lItak!es2arguments;key\aisthecharacterthatyouwanttobind,wandfunctionistheaddressofthefunctiontorunwhenk!eyispressed.BindingTABtorl_insertf()makesTABjustfinsertitself.rl_bind_keyf()returnsnon-zeroifk!eyisnotavdDalidASCIMIcharactercoMde(bet!ween0and255).Url_bind_key('\t',rl_insert); UChapterf2:ProgrammingwithGNUReadline133ڍЍThisXcoMdeshouldbeexecutedonceatthestartofy!ourprogram;youmightwriteafunctioncalledinitialize_readlinef()whic!hpMerformsthisandotherdesiredinitializations,suchasinstallingcustomfcompleters,etc.5Ze@2.2CustomffFfunctions!Readlinepro!videsagreatmanyfunctionsformanipulatingthetextoftheline.Butitisn'tpMossibletoan!ticipatetheneedsofallprograms.ThissectiondescribesthevdDariousfunctionsandvdDariables֠de nedinwithintheReadlinelibrarywhic!hallowauserprogramtoaddcustomizedfunctionalit!yftoReadline.1ZeE2.2.1d(ThepFģunctionTypieFeor}thesak!eofreadabiltye,wedeclareanewtypMeofobject,calledFeunction.[A}FunctionisaClanguageffunctionwhic!hreturnsanint.ThetypMedeclarationforFunctionis:typedeffintFunction();Thereasonfordeclaringthisnewt!ypMeistomakeiteasiertowritecoMdedescribingpoin!terstoCfunctions.Letussa!ywehadavdDariablecalledfuncwhichwasapMointertoafunction.InsteadofftheclassicCdeclarationintf(*)()func;w!efhaveFunctionf*func;1ZeE2.2.2d(NamingpaFģunctionTheUusercandynamicallyc!hangethebindingsofkeyswhileusingReadline.Thisisdonebyrepresen!ting thefunctionwithadescriptivename. TheuserisabletotypMethedescriptivenamewhenfreferringtothefunction.Th!us,inaninit le,onemight ndUMeta-Rubout: Tbackward-kill-word\k14]+GNUfReadlineLibrary3ڍЍThisbindsthek!eystrokeMETA-RUBOUTtothefunctiondescriptiv!elynamedbackward-kill-word.kYeou,aastheprogrammer,shouldbindthefunctionsy!ouwritetodescriptivenamesaswell.Readlinefpro!videsafunctionfordoingthat:(FeunctionU9"V cmbx10rl#؎add#؎defuny7m#R 3 cmss10(c!harf*name,Feunction*function,intkey)UAddnameMtothelistofnamedfunctions.Mak!efunctionbMethefunctionthatgetsUcalled.Iffk!ey~isnot-1,thenbindittofunctionusingrl_bind_key().Usingthisfunctionaloneissucien!tformostapplications.ItistherecommendedwaytoaddafewQ functionstothedefaultfunctionsthatReadlinehasbuiltinalreadye.iIfy!ouneedtodomoreordi eren!tethingsthanaddingafunctiontoReadline,eyoumayneedtousetheunderlyingfunctionsdescribMedfbelo!w.5[E2.2.3d(SelectingpaKeymap!_KeypQbindingstak!eplaceonakeymap.;ThekeymapistheassoMciationbet!weenpQthek!eysthattheusert!ypMesandthefunctionsthatgetrun.xYeoucanmakeyourownkeymaps,Bcopyexistingk!eymaps,fandtellReadlinewhichkeymaptouse.FeunctionUKeymaprl#؎make#؎bare#؎keymapy()UReturns1anew,Iempt!ykeymap.ThespaceforthekeymapisalloMcatedwithmallocf();Uy!oufshouldfree()itwhenyouaredone.FeunctionUKeymaprl#؎copy#؎keymapy(Keymapfmap)UReturnfanewk!eymapwhichisacopyofmap.FeunctionUKeymaprl#؎make#؎keymapy()UReturnoanewk!eymapwiththeprintingcharactersbMoundtorl/xH'insert,,thelowercaseUMetaFjc!haractersbMoundtoruntheirequivdDalents,YandtheMetadigitsbMoundtoproduceUn!umericfarguments.5[E2.2.4d(BindingpKeys!_YeoufassoMciatek!eyswithfunctionsthroughthekeymap.Herearefunctionsfordoingthat.cChapterf2:ProgrammingwithGNUReadline153ڍЍFeunctionUintrl#؎bind#؎keyy(in!tfkeye,Function*function)UBindsQk!eyitofunctioninthecurrentlyselectedkeymap.jReturnsnon-zerointhecaseUoffanin!vdDalidkey.*dFeunctionUintrl#؎bind#؎key#؎in#؎mapy(in!tfkeye,Function*function,KeymapNUmap)UBindfk!ey~tofunctioninmap.Returnsnon-zerointhecaseofaninvdDalidkey.*dFeunctionUintrl#؎unbind#؎keyy(in!tfkey)UMak!ejMkeyZedonothinginthecurrentlyselectedkeymap.)Returnsnon-zeroincaseofUerror.*dFeunctionUintrl#؎unbind#؎key#؎in#؎mapy(in!tfkeye,Keymapmap)UMak!efkey~bMeboundtothen!ullfunctioninmap.Returnsnon-zeroincaseoferror.FeunctionUrl#؎generic#؎bindy(in!tftypMe,char*keyseq,char*data,Keymapmap)UBindCthek!eysequencerepresentedbythestringkeyseq)tothearbitrarypMointerdata.Ut!ypMesayscwhatkindofdataispoin!tedtobydata;lrightnowthiscanbMeafunctionU(ISFUNC),a$Zmacro(ISMACR),orak!eymap(ISKMAP). WThismakesnewkeymapsasUnecessarye.Thefinitialplacetodobindingsisinmap.<-׍E2.2.5d(WģritingpaNewFunction"!InordertowritenewfunctionsforReadline,|y!ouneedtoknowthecallingconventionsfork!eybMoard]invokedfunctions,andthenamesofthevdDariablesthatdescribMethecurrentstateofthelinefgatheredsofar.*d%VeariableUchary*rl/xH'line/xHbu erUThisisthelinegatheredsofar.Yeouarew!elcometomoMdifythecontentsofthis,!.butUseefUndoing,bMelo!w.*d%VeariableUintyrl/xH'pMoin!tUThefo setofthecurren!tcursorpMositioninrl/xH'line/xHbu er.m[16]+GNUfReadlineLibrary3ڍЍ%VeariableUintyrl/xH'endUThen!umbMerofcharacterspresentinrl_line_buffer.Whenrl_pointisattheendUofftheline,thenrl_pointandrl_endareequal.*dÍThefcallingsequenceforacommandfooloMokslik!e"!Ufoo(intcount,intkey)whereC coun!t isthenumericargument(or1ifdefaulted)andkey38isthekeythatinvokedthisfunction.ItRiscompletelyuptothefunctionastowhatshouldbMedonewiththen!umericargument;nsomefunctions=useitasarepMeatcoun!t,Eotherfunctionsasa ag,andsomec!hoMosetoignoreit.Ingeneral,ifAWafunctionusesthen!umericargumentasarepMeatcount,UitshouldbMeabletodosomethingusefulwith4anegativ!eargumentaswellasapMositiveargument.Attheveryleast,KitshouldbMeawarethatitfcanbMepassedanegativ!eargument.<.IE2.2.6d(AllowingpUndoingSuppMortingtheundocommandisapainlessthingtodo,andmak!esyourfunctionsmuchmoreusefultotheenduser.Itiscertainlyeasytotrysomethingify!ouknowyoucanundoit.IcouldusefanundofunctionforthestoMc!kmarket.Ify!ourfunctionsimplyinsertstextonce,iordeletestextonce,anditcallsrl_insert_textf()orFrl_delete_textf()todoit,thenundoingisalreadydonefory!ouautomaticallye,andy!oucansafelyfskipthissection.Ify!oudomultipleinsertionsormultipledeletions,oranycombinationoftheseopMerations,youshouldƭgroupthemtogetherin!tooneopMeration.>Thiscanbedonewithrl_begin_undo_groupf()andfrl_end_undo_group().*dÍFeunctionUrl#؎bb"egin#؎undo#؎groupy()UBeginsEsa!vingundoinformationinagroupconstruct.;TheundoinformationusuallyUcomesl"fromcallstorl_insert_textf()andrl_delete_text(),buttheycouldbMeUdirectfcallstorl_add_undo().w+Chapterf2:ProgrammingwithGNUReadline173ڍЍFeunctionUrl#؎end#؎undo#؎groupy()UCloses-thecurren!tundogroupstartedwithrl_begin_undo_groupf().t ThereshouldUbMe7exactlyonecalltorl_end_undo_groupf()forev!erycalltorl_begin_undo_groupU().'6Finallye,ify!ouneitherinsertnordeletetext,butdirectlymoMdifytheexistingtext(e.g.`tc!hangeits3ucase),Vy!oucallrl_modifyingf()once,justbMeforey!oumodifythetext. Yeoum!ustsupplytheindicesfofthetextrangethaty!ouaregoingtomoMdifye.FeunctionUrl#؎mob"difyingy(in!tfstart,intend)UTeellReadlinetosa!vethetextbMet!weenstartandend"*asasingleundounit.ItisassumedUthatfsubsequen!ttothiscallyouwillmoMdifythatrangeoftextinsomewaye.3E2.2.7d(AnpExample!.Hereisafunctionwhic!hchangeslowercasecharacterstotheuppMercaseequivdDalents,randuppMer-case}c!haracterstothelowercaseequivdDalents.IfthisfunctionwasbMoundto`M-c',Xthentyping`M-c'w!ouldchangethecaseofthecharacterunderpMoint.nTyping`10fM-c'wouldchangethecaseofthefollo!wingf10characters,leavingthecursoronthelastcharacterchanged.U/*InvertthecaseoftheCOUNTfollowingcharacters.*/ Uinvert_case_line(count,key)9intcount,key;U{(gregisterintstart,end;(gstart=rl_point;(gif(count<0) 3{?fQdirection=-1;?fQcount=-count;3}(gelse3direction=1;(g/*Findtheendoftherangetomodify.*/(gend=start+(count*direction);(g/*Forceittobewithinrange.*/(gif(end>rl_end)3end=rl_end;E18]+GNUfReadlineLibrary3ڍЍ(gelseif(end<0) 3end=-1;(gif(start>end)3{?fQinttemp=start;?fQstart=end;?fQend=temp;3}(gif(start==end)3return;(g/*Tellreadlinethatwearemodifyingtheline,sosavetheundo9information.*/(grl_modifying(start,end);(gfor(;start!=end;start+=direction)3{?fQif(uppercase_p(rl_line_buffer[start]))Jrl_line_buffer[start]=to_lower(rl_line_buffer[start]);?fQelseif(lowercase_p(rl_line_buffer[start]))Jrl_line_buffer[start]=to_upper(rl_line_buffer[start]);3}(g/*Movepointtoontopofthelastcharacterchanged.*/(grl_point=end-direction;U}4@2.3CustomffCompleters!T!ypicallye,aprogramthatreadscommandsfromtheuserhasawayofdisambiguatingbMetweencommandsanddata.m4Ify!ourprogramisoneofthese,uthenitcanprovidecompletionforeithercommands,#orRdata,orbMothcommandsanddata.,Thefollo!wingsectionsdescribeho!wyourprogramandfReadlinecoMoperateftopro!videthisservicetoendusers.0E2.3.1d(HowpCompletingWģorksIny!ordertocompletesometext,thefulllistofpMossiblecompletionsm!ustbea!vdDailable.V ThatisM8tosa!ye,vitisnotpMossibletoaccuratelyexpandapartialwordwithoutknowingwhatallofthepMossiblew!ordsthatmakesenseinthatcontextare.¦TheGNUReadlinelibraryprovidestheuserin!terfacetocompletion,andadditionallye,t!woofthemostcommoncompletionfunctions;t lenameandusername.?Feorcompletingothert!ypMesoftext,youmustwriteyourowncompletionfunction.ThisfsectiondescribMesexactlywhatthosefunctionsm!ustdo,andprovidesanexamplefunction.Chapterf2:ProgrammingwithGNUReadline193ڍЍTherefarethreemajorfunctionsusedtopMerformcompletion:!1.dThe3user-in!terfacefunctionrl_completef().EThisfunctioniscalledinteractivelywiththedsamew%callingcon!ventionsw%asotherfunctionsinreadlinein!tendedforinteractiveuse;i.e.count,dand Uen!try/xH'function9isafunctionoftwoargs,=nandreturnsa(charf*).HWThe rstargumentUis@atext. Thesecondisastateargumen!t; ^itiszeroonthe rstcall,andnon-zeroUonpsubsequen!tcalls.=ItreturnsaNULLpMointertothecallerwhentherearenomoreUmatc!hes.'$FeunctionUchar* lename#؎completion#؎functiony(c!harf*text,intstate)UA 2generator Xfunctionfor lenamecompletioninthegeneralcase.NotethatcompletionUin theBashshellisalittledi eren!tbMecauseofallthepathnamesthatmustbMefollowedUwhenfloMokingupthecompletionforacommand.'$FeunctionUchar*username#؎completion#؎functiony(c!harf*text,intstate)UA`completionxgeneratorforusernames.textCxcon!tainsapartialusernameprecededbyUafrandomc!haracter(usually`~').4.nE2.3.3d(CompletionpVģariables'$%VeariableUFٚunctiony*rl/xH'completion/xHen!try/xHfunctionUA#pMoin!ter#tothegeneratorfunctionforcompletion_matchesf().UNULLmeanstouseUfilename_entry_functionf(),thedefault lenamecompleter.}Chapterf2:ProgrammingwithGNUReadline213ڍЍ%VeariableUFٚunctiony*rl/xH'attempted/xHcompletion/xHfunctionUApMoin!tertoanalternativefunctiontocreatematches.ThefunctioniscalledwithUtext,4start,andend.startѥandendareindicesinrl_line_buffersa!yingwhattheUbMoundariesCoftext%Care.tIfthisfunctionexistsandreturnsNULLthenrl_completef()UwillcallthevdDalueofrl_completion_entry_functiontogeneratematc!hes,otherwiseUthefarra!yofstringsreturnedwillbMeused.&o⍍%VeariableUintyrl/xH'completion/xHquery/xHitemsUUptothisman!yitemswillbMedisplayedinrespMonsetoapossible-completionscall.UAfterRthat,Lw!easktheuserifsheissureshewantstoseethemall.aThedefaultvdDalueUisf100.%VeariableUchary*rl/xH'basic/xHw!ord/xHbreak/xHcharactersUThe basiclistofc!haractersthatsignalabreakbMetweenwordsforthecompleterrou-Utine. mThe+con!tentsofthisvdDariableiswhatbreakswordsintheBashshell,i.e. m"U\t\n\"\\'`@$><=".%VeariableUchary*rl/xH'completer/xHw!ord/xHbreak/xHcharactersUTheIflistofc!haractersthatsignalabreakbMetweenwordsforrl_complete_internalU().Thefdefaultlististhecon!tentsfofrl_basic_word_break_characters.%VeariableUchary*rl/xH'spMecial/xHpre xesUTheqlistofc!haractersthatarewordbreakcharacters,ٴbutshouldbMeleftintext qwhenUiteispassedtothecompletionfunction.ProgramscanusethistohelpdeterminewhatUkindfofcompletingtodo.%VeariableUintyrl/xH'ignore/xHcompletion/xHduplicatesUIffnon-zero,thendisallo!wduplicatesinthematches.Defaultis1.%VeariableUintyrl/xH' lename/xHcompletion/xHdesiredUNon-zeroDmeansthattheresultsofthematc!hesaretobMetreatedas lenames.ThisUistalw!ays)zeroonentrye,xandcanonlybMechangedwithinacompletionentrygeneratorUfunction.%VeariableUFٚunctiony*rl/xH'ignore/xHsome/xHcompletions/xHfunctionUThis.function,Oifde ned,iscalledb!ythecompleterwhenreal lenamecompletionisUdone,after|9allthematc!hingnameshavebMeengenerated._UItispassedaNULLtermi-x22]+GNUfReadlineLibrary3ڍЍUnated+arra!yofpMointersto(charf*)knownasmatchessinthecoMde.n}The1stelementU(matches[0])wisthemaximalsubstringthatiscommontoallmatc!hes.SThisfunctionUcanDre-arrangethelistofmatc!hesasrequired,lbuteachdeletedelementofthearrayUm!ustfbMefree()'d.2E2.3.4d(ApShortCompletionExample!HereisasmallapplicationdemonstratingtheuseoftheGNUReadlinelibrarye.0Itiscalledfileman,aand`thesourcecoMderesidesin`readline/examples/fileman.c'.Thissampleapplicationpro!videsfcompletionofcommandnames,lineeditingfeatures,andaccesstothehistorylist.Chapterf2:ProgrammingwithGNUReadline233ڍЍU/*fileman.c--Atinyapplicationwhichdemonstrateshowtousethe .'SGNUReadlinelibrary. TThisapplicationinteractivelyallowsusers.'Stomanipulatefilesandtheirmodes.*/U#includeU#includeU#includeU#includeU#includeU#includeU#includeU/*Thenamesoffunctionsthatactuallydothemanipulation.*/Uintcom_list(),com_view(),com_rename(),com_stat(),com_pwd();Uintcom_delete(),com_help(),com_cd(),com_quit();U/*Astructurewhichcontainsinformationonthecommandsthisprogram.'Scanunderstand.*/Utypedefstruct{(gchar*name;m9/*Userprintablenameofthefunction.*/(gFunction*func;V:/*Functiontocalltodothejob.*/(gchar*doc;rH/*Documentationforthisfunction. T*/U}COMMAND;UCOMMANDcommands[]={(g{"cd",com_cd,"ChangetodirectoryDIR"},(g{"delete",com_delete,"DeleteFILE"},(g{"help",com_help,"Displaythistext"},(g{"?",com_help,"Synonymfor`help'"},(g{"list",com_list,"ListfilesinDIR"},(g{"ls",com_list,"Synonymfor`list'"},(g{"pwd",com_pwd,"Printthecurrentworkingdirectory"},(g{"quit",com_quit,"QuitusingFileman"},(g{"rename",com_rename,"RenameFILEtoNEWNAME"},(g{"stat",com_stat,"PrintoutstatisticsonFILE"},(g{"view",com_view,"ViewthecontentsofFILE"},(g{(char*)NULL,(Function*)NULL,(char*)NULL}U};U/*Thenameofthisprogram,astakenfromargv[0].*/Uchar*progname;U/*Whennon-zero,thisglobalmeanstheuserisdoneusingthisprogram.*/Uintdone=0;Í24]+GNUfReadlineLibrary3ڍЍUmain(argc,argv) 9intargc;9char**argv;U{(gprogname=argv[0];(ginitialize_readline();(=/*Bindourcompleter.*/(g/*Loopreadingandexecutinglinesuntiltheuserquits.*/ (gwhile(!done)3{?fQchar*line;?fQline=readline("FileMan:");?fQif(!line) J{Vddone=1;J/*EncounteredEOFattoplevel.*/J}?fQelseJ{Vd/*Removeleadingandtrailingwhitespacefromtheline.gThen,ifthereisanythingleft,addittothehistorylistgandexecuteit.*/Vdstripwhite(line);Vdif(*line)aM{mcadd_history(line);mcexecute_line(line);aM}J}?fQif(line)Jfree(line);3}(gexit(0);U}U/*Executeacommandline.*/Uexecute_line(line)9char*line;U{(gregisterinti;(gCOMMAND*find_command(),*command;(gchar*word;(g/*Isolatethecommandword.*/(gi=0;čChapterf2:ProgrammingwithGNUReadline253ڍЍ(gwhile(line[i]&&!whitespace(line[i])) 3i++;(gword=line;(gif(line[i])3line[i++]='\0';(gcommand=find_command(word);(gif(!command)3{?fQfprintf(stderr,"%s:NosuchcommandforFileMan.\n",word);?fQreturn;3}(g/*Getargumenttocommand,ifany.*/(gwhile(whitespace(line[i]))3i++;(gword=line+i;(g/*Callthefunction.*/(g(*(command->func))(word);U}U/*LookupNAMEasthenameofacommand,andreturnapointertothat.'Scommand. TReturnaNULLpointerifNAMEisn'tacommandname.*/UCOMMAND*Ufind_command(name)9char*name;U{(gregisterinti;(gfor(i=0;commands[i].name;i++)3if(strcmp(name,commands[i].name)==0)?fQreturn(&commands[i]);(greturn((COMMAND*)NULL);U}U/*StripwhitespacefromthestartandendofSTRING.*/Ustripwhite(string)9char*string;U{(gregisterinti=0;(gwhile(whitespace(string[i]))3i++;^26]+GNUfReadlineLibrary3ڍЍ(gif(i) 3strcpy(string,string+i);(gi=strlen(string)-1;(gwhile(i>0&&whitespace(string[i]))3i--;(gstring[++i]='\0';U}MChapterf2:ProgrammingwithGNUReadline273ڍЍU/******************************************************************/ U/*{i*/U/*gyInterfacetoReadlineCompletion[*/U/*{i*/U/******************************************************************/U/*TelltheGNUReadlinelibraryhowtocomplete. TWewanttotrytocomplete.'Soncommandnamesifthisisthefirstwordintheline,oronfilenames.'Sifnot.*/Uinitialize_readline()U{(gchar**fileman_completion();(g/*Allowconditionalparsingofthe~/.inputrcfile.*/(grl_readline_name="FileMan";(g/*Tellthecompleterthatwewantacrackfirst.*/(grl_attempted_completion_function=(Function*)fileman_completion;U}U/*AttempttocompleteonthecontentsofTEXT. TSTARTandENDshowthe.'SregionofTEXTthatcontainsthewordtocomplete. TWecanusethe.'Sentirelineincasewewanttodosomesimpleparsing. TReturnthe.'Sarrayofmatches,orNULLiftherearen'tany.*/Uchar**Ufileman_completion(text,start,end)9char*text;9intstart,end;U{(gchar**matches;(gchar*command_generator();(gmatches=(char**)NULL;(g/*Ifthiswordisatthestartoftheline,thenitisacommand9tocomplete. TOtherwiseitisthenameofafileinthecurrent9directory.*/(gif(start==0)3matches=completion_matches(text,command_generator);(greturn(matches);U}U/*Generatorfunctionforcommandcompletion. TSTATEletsusknowwhether.'Stostartfromscratch;withoutanystate(i.e.STATE==0),thenwe.'Sstartatthetopofthelist.*/Uchar*Ucommand_generator(text,state)9char*text;s28]+GNUfReadlineLibrary3ڍЍ9intstate; U{(gstaticintlist_index,len;(gchar*name;(g/*Ifthisisanewwordtocomplete,initializenow. TThisincludes9savingthelengthofTEXTforefficiency,andinitializingtheindex9variableto0.*/(gif(!state)3{?fQlist_index=0;?fQlen=strlen(text);3}(g/*Returnthenextnamewhichpartiallymatchesfromthecommandlist.*/(gwhile(name=commands[list_index].name)3{?fQlist_index++;?fQif(strncmp(name,text,len)==0)Jreturn(name);3}(g/*Ifnonamesmatched,thenreturnNULL.*/(greturn((char*)NULL);U}8Chapterf2:ProgrammingwithGNUReadline293ڍЍU/******************************************************************/ U/*{i*/U/*8FFileManCommands6*/U/*{i*/U/******************************************************************/U/*Stringtopasstosystem(). TThisisfortheLIST,VIEWandRENAME.'Scommands.*/Ustaticcharsyscom[1024];U/*Listthefile(s)namedinarg.*/Ucom_list(arg)9char*arg;U{(gsprintf(syscom,"ls-FClg%s",arg);(gsystem(syscom);U}Ucom_view(arg)9char*arg;U{(gif(!valid_argument("view",arg))3return;(gsprintf(syscom,"cat%s|more",arg);(gsystem(syscom);U}Ucom_rename(arg)9char*arg;U{(gtoo_dangerous("rename");U}Ucom_stat(arg)9char*arg;U{(gstructstatfinfo;(gif(!valid_argument("stat",arg))3return;(gif(stat(arg,&finfo)==-1)3{?fQperror(arg);?fQreturn;3}(gprintf("Statisticsfor`%s':\n",arg);\30]+GNUfReadlineLibrary3ڍЍ(gprintf("%shas%dlink%s,andis%dbytesinlength.\n",arg, Vdfinfo.st_nlink,(finfo.st_nlink==1)?"":"s", Tfinfo.st_size);(gprintf(""}Createdon:%s",ctime(&finfo.st_ctime));(gprintf(" TLastaccessat:%s",ctime(&finfo.st_atime));(gprintf("Lastmodifiedat:%s",ctime(&finfo.st_mtime));U}Ucom_delete(arg)9char*arg;U{(gtoo_dangerous("delete");U}U/*PrintouthelpforARG,orforallofthecommandsifARGis.'Snotpresent.*/Ucom_help(arg)9char*arg;U{(gregisterinti;(gintprinted=0;(gfor(i=0;commands[i].name;i++)3{?fQif(!*arg||(strcmp(arg,commands[i].name)==0))J{Vdprintf("%s\t\t%s.\n",commands[i].name,commands[i].doc);Vdprinted++;J}3}(gif(!printed)3{?fQprintf("Nocommandsmatch`%s'. TPossibiltiesare:\n",arg);?fQfor(i=0;commands[i].name;i++)J{Vd/*Printinsixcolumns.*/Vdif(printed==6)aM{mcprinted=0;mcprintf("\n");aM}Vdprintf("%s\t",commands[i].name);Vdprinted++;J}?fQif(printed)Jprintf("\n");?Chapterf2:ProgrammingwithGNUReadline313ڍЍ3} U}U/*ChangetothedirectoryARG.*/Ucom_cd(arg)9char*arg;U{(gif(chdir(arg)==-1)3perror(arg);(gcom_pwd("");U}U/*Printoutthecurrentworkingdirectory.*/Ucom_pwd(ignore)9char*ignore;U{(gchardir[1024];(g(void)getwd(dir);(gprintf("Currentdirectoryis%s\n",dir);U}U/*Theuserwishestoquitusingthisprogram. TJustsetDONEnon-zero.*/Ucom_quit(arg)9char*arg;U{(gdone=1;U}U/*Functionwhichtellsyouthatyoucan'tdothis.*/Utoo_dangerous(caller)9char*caller;U{(gfprintf(stderr,\$"%s:Toodangerousformetodistribute. TWriteityourself.\n",\$caller);U}U/*Returnnon-zeroifARGisavalidargumentforCALLER,elseprint.'Sanerrormessageandreturnzero.*/UintUvalid_argument(caller,arg)9char*caller,*arg;U{(gif(!arg||!*arg)3{?fQfprintf(stderr,"%s:Argumentrequired.\n",caller);?fQreturn(0); ߨ32]+GNUfReadlineLibrary3ڍЍ3}(greturn(1); U}!位AppMendixfA:ConceptIndexC<333ڍЍApp=endixzA QConceptIndex4\(o cmr9(IndexTisempt9y)"O34]+GNUfReadlineLibrary3ڟ# AppMendixfB:FeunctionandVariableIndex353ڍЍApp=endixzB QFaGunctionandVariableIndex4\((IndexTisempt9y)$怍36]+GNUfReadlineLibrary3ڟcҶi3ڍЍTaGablezofConutents)Bd@132CommandffLineEditingT b> cmmi10:qōT:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:$@1$1.1 5In!troMductionftoLineEditing͍T:qōT:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:1$1.2 5ReadlinefIn!teraction8T:qōT:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:r1H1.2.1 5ReadlinefBareEssen!tialsT:qōT:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:u2H1.2.2 5ReadlinefMo!vementCommandsT:qōT:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:2H1.2.3 5ReadlinefKillingCommandsdT:qōT:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:w3H1.2.4 5ReadlinefArgumen!ts'T:qōT:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:_3$1.3 5ReadlinefInitFile/T:qōT:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:I4H1.3.1 5ReadlinefInitSyn!taxIT:qōT:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:r4l1.3.1.1 5CommandsfFeorMo!vingUET:qōT:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:5l1.3.1.2 5CommandsfFeorManipulatingTheHistory㍑T:qōT:T:T:T:T:T:T:a5l1.3.1.3 5CommandsfFeorChangingTextQ%T:qōT:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:6l1.3.1.4 5KillingfAndYeankingS卑T:qōT:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:Š7l1.3.1.5 5SpMecifyingfNumericArgumen!tsݍT:qōT:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:o7l1.3.1.6 5LettingfReadlineT!ypMeFeorYouZZT:qōT:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:8l1.3.1.7 5SomefMiscellaneousCommandsT:qōT:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T: i8H1.3.2 5ReadlinefViMoMde7T:qōT:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:8@232ProgrammingffwithGNUReadline⍑T:qōT:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:?@11$2.1 5DefaultfBeha!viour4[T:qōT:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:11$2.2 5CustomfFeunctionscT:qōT:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:13H2.2.1 5ThefFeunctionT!ypMeT:qōT:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:0@13H2.2.2 5NamingfaFeunction bT:qōT:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:~13H2.2.3 5SelectingfaKeymapfT:qōT:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:E!14H2.2.4 5BindingfKeys8T:qōT:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:14H2.2.5 5WeritingfaNewFunctionHT:qōT:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:15H2.2.6 5Allo!wingfUndoing񢍑T:qōT:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:c^16H2.2.7 5AnfExampleT:qōT:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:517$2.3 5CustomfCompleters'T:qōT:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:a18H2.3.1 5Ho!wfCompletingWeorks=eT:qōT:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T: 18H2.3.2 5CompletionfFeunctions%T:qōT:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:19H2.3.3 5CompletionfVeariables3FT:qōT:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:20H2.3.4 5AfShortCompletionExampleb6T:qōT:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:22@Apps3endixffA32ConceptIndexvӍT:qōT:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:@33!Apps3endixffB32FfunctionandVariableIndexnT:qōT:T:T:T:T:T:T:T:T:T:T:T:T:T:T:T:P@35ÍiibGNUfReadlineLibrary3ڟD;3G(JNj cmbx12EN # cmbx12@Nff cmbx12;NG cmbx129"V cmbx107m#R 3 cmss106p0J 3 cmsl103 cmmi10o cmr9