1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987 |
- ;;; ido.el --- interactively do things with buffers and files -*- lexical-binding: t -*-
- ;; Copyright (C) 1996-2017 Free Software Foundation, Inc.
- ;; Author: Kim F. Storm <storm@cua.dk>
- ;; Based on: iswitchb by Stephen Eglen <stephen@cns.ed.ac.uk>
- ;; Keywords: extensions convenience
- ;; This file is part of GNU Emacs.
- ;; GNU Emacs is free software: you can redistribute it and/or modify
- ;; it under the terms of the GNU General Public License as published by
- ;; the Free Software Foundation, either version 3 of the License, or
- ;; (at your option) any later version.
- ;; GNU Emacs is distributed in the hope that it will be useful,
- ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
- ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ;; GNU General Public License for more details.
- ;; You should have received a copy of the GNU General Public License
- ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
- ;;; Commentary:
- ;; Ido - interactive do - switches between buffers and opens files and
- ;; directories with a minimum of keystrokes. It is a superset of
- ;; iswitchb, the interactive buffer switching package by Stephen Eglen.
- ;; Interactive substring matching
- ;; ------------------------------
- ;;
- ;; As you type in a substring, the list of buffers or files currently
- ;; matching the substring are displayed as you type. The list is
- ;; ordered so that the most recent buffers or files visited come at
- ;; the start of the list.
- ;;
- ;; The buffer or file at the start of the list will be the one visited
- ;; when you press RETURN. By typing more of the substring, the list is
- ;; narrowed down so that gradually the buffer or file you want will be
- ;; at the top of the list. Alternatively, you can use C-s and C-r (or
- ;; the right and left arrow keys) to rotate buffer or file names in the
- ;; list until the one you want is at the top of the list.
- ;;
- ;; Completion is also available so that you can see what is common to
- ;; all of the matching buffers or files as you type.
- ;;
- ;; Example:
- ;;
- ;; If I have two buffers called "123456" and "123", with "123456" the
- ;; most recent, when I use ido-switch-buffer, I first of all get
- ;; presented with the list of all the buffers
- ;;
- ;; Buffer: {123456 | 123}
- ;;
- ;; If I then press 2:
- ;; Buffer: 2[3]{123456 | 123}
- ;;
- ;; The list in {...} are the matching buffers, most recent first
- ;; (buffers visible in the current frame are put at the end of the
- ;; list by default). At any time I can select the item at the head of
- ;; the list by pressing RET. I can also put the first element at the
- ;; end of the list by pressing C-s or [right], or bring the last
- ;; element to the head of the list by pressing C-r or [left].
- ;;
- ;; The item in [...] indicates what can be added to my input by
- ;; pressing TAB. In this case, I will get "3" added to my input.
- ;; So, I press TAB:
- ;; Buffer: 23{123456 | 123}
- ;;
- ;; At this point, I still have two matching buffers.
- ;; If I want the first buffer in the list, I simply press RET. If I
- ;; wanted the second in the list, I could press C-s to move it to the
- ;; top of the list and then RET to select it.
- ;;
- ;; However, if I type 4, I only have one match left:
- ;; Buffer: 234[123456]
- ;;
- ;; Since there is only one matching buffer left, it is given in [] and
- ;; it is shown in the `ido-only-match' face (ForestGreen). I can now
- ;; press TAB or RET to go to that buffer.
- ;;
- ;; If I want to create a new buffer named "234", I press C-j instead of
- ;; TAB or RET.
- ;;
- ;; If instead, I type "a":
- ;; Buffer: 234a [No match]
- ;; There are no matching buffers. If I press RET or TAB, I can be
- ;; prompted to create a new buffer called "234a".
- ;;
- ;; Of course, where this function comes in really useful is when you
- ;; can specify the buffer using only a few keystrokes. In the above
- ;; example, the quickest way to get to the "123456" file would be
- ;; just to type 4 and then RET (assuming there isn't any newer buffer
- ;; with 4 in its name).
- ;; Likewise, if you use C-x C-f (ido-find-file), the list of files and
- ;; directories in the current directory is provided in the same
- ;; fashion as the buffers above. The files and directories are
- ;; normally sorted in alphabetical order, but the most recently
- ;; visited directory is placed first to speed up navigating to
- ;; directories that you have visited recently.
- ;;
- ;; In addition to scrolling through the list using [right] and [left],
- ;; you can use [up] and [down] to quickly scroll the list to the next
- ;; or previous subdirectory.
- ;;
- ;; To go down into a subdirectory, and continue the file selection on
- ;; the files in that directory, simply move the directory to the head
- ;; of the list and hit RET.
- ;;
- ;; To go up to the parent directory, delete any partial file name
- ;; already specified (e.g. using [backspace]) and hit [backspace].
- ;;
- ;; To go to the root directory (on the current drive), enter two
- ;; slashes. On MS-DOS or Windows, to select the root of another
- ;; drive, enter X:/ where X is the drive letter. You can also visit
- ;; files on other hosts using the ange-ftp notations `/host:' and
- ;; `/user@host:'. See the variable `ido-slow-ftp-hosts' if you want
- ;; to inhibit the ido substring matching for ftp access.
- ;;
- ;; If for some reason you cannot specify the proper file using
- ;; ido-find-file, you can press C-f to enter the normal find-file.
- ;; You can also press C-b to drop into ido-switch-buffer.
- ;; See the doc string of ido-switch-buffer and ido-find-file for full
- ;; keybindings and features.
- ;; (describe-function 'ido-find-file)
- ;; Hidden buffers and files
- ;; ------------------------
- ;;
- ;; Normally, ido does not include hidden buffers (whose name starts
- ;; with a space) and hidden files and directories (whose name starts
- ;; with `.') in the list of possible completions. However, if the
- ;; substring you enter does not match any of the visible buffers or
- ;; files, ido will automatically look for completions among the hidden
- ;; buffers or files.
- ;;
- ;; You can toggle display of the hidden buffers and files with C-a.
- ;; Additional functionality
- ;; ------------------------
- ;;
- ;; After C-x b, the buffer at the head of the list can be killed by
- ;; pressing C-k. If the buffer needs saving, you will be queried
- ;; before the buffer is killed.
- ;;
- ;; Likewise, after C-x C-f, you can delete (i.e. physically remove)
- ;; the file at the head of the list with C-k. You will always be
- ;; asked for confirmation before the file is deleted.
- ;;
- ;; If you enter C-x b to switch to a buffer visiting a given file, and
- ;; you find that the file you are after is not in any buffer, you can
- ;; press C-f to immediately drop into ido-find-file. And you can
- ;; switch back to buffer selection with C-b.
- ;; Prefix matching
- ;; ---------------
- ;;
- ;; The standard way of completion with Unix-shells and Emacs is to insert a
- ;; PREFIX and then hitting TAB (or another completion key). Cause of this
- ;; behavior has become second nature to a lot of Emacs users, Ido offers in
- ;; addition to the default substring-matching-method (look above) also the
- ;; prefix-matching-method. The kind of matching is the only difference to
- ;; the description of the substring-matching above.
- ;;
- ;; You can toggle prefix matching with C-p.
- ;;
- ;; Example:
- ;;
- ;; If you have again two Buffers "123456" and "123" then hitting "2" does
- ;; not match because "2" is not a PREFIX in any of the buffer-names.
- ;; Flexible matching
- ;; -----------------
- ;;
- ;; If you set ido-enable-flex-matching, ido will do a more flexible
- ;; matching (unless regexp matching is active) to find possible matches
- ;; among the available buffer or file names if no matches are found using
- ;; the normal prefix or substring matching.
- ;;
- ;; The flexible matching implies that any item which simply contains all
- ;; of the entered characters in the specified sequence will match.
- ;;
- ;; Example:
- ;;
- ;; If you have four files "alpha", "beta", "gamma", and "delta",
- ;; entering "aa" will match "alpha" and "gamma", while "ea" matches
- ;; "beta" and "delta". If prefix matching is also active, "aa" only
- ;; matches "alpha", while "ea" does not match any files.
- ;; Regexp matching
- ;; ---------------
- ;;
- ;; There is limited provision for regexp matching within ido,
- ;; enabled through `ido-enable-regexp' (toggle with C-t).
- ;; This allows you to type `[ch]$' for example and see all file names
- ;; ending in `c' or `h'.
- ;;
- ;; Note: ido-style completion is inhibited when you enable regexp matching.
- ;; Customization
- ;; -------------
- ;;
- ;; Customize the Ido group to change the Ido functionality.
- ;;
- ;; To modify the keybindings, use `define-key' on
- ;; `ido-common-completion-map' or one of the specialized keymaps:
- ;; `ido-file-dir-completion-map', `ido-file-completion-map' or
- ;; `ido-buffer-completion-map'.
- ;;
- ;; (with-eval-after-load 'ido
- ;; (define-key ido-common-completion-map " " 'ido-next-match))
- ;; Seeing all the matching buffers or files
- ;; ----------------------------------------
- ;;
- ;; If you have many matching files, they may not all fit onto one
- ;; line of the minibuffer. Normally, the minibuffer window will grow
- ;; to show you more of the matching files (depending on the setting
- ;; of the variables `resize-mini-windows' and `max-mini-window-height').
- ;; If you want ido to behave differently from the default minibuffer
- ;; resizing behavior, set the variable `ido-max-window-height'.
- ;;
- ;; Also, to improve the responsiveness of ido, the maximum number of
- ;; matching items is limited to 12, but you can increase or removed
- ;; this limit via the `ido-max-prospects' variable.
- ;; To see a full list of all matching buffers in a separate buffer,
- ;; hit ? or press TAB when there are no further completions to the
- ;; substring. Repeated TAB presses will scroll you through this
- ;; separate buffer.
- ;; Changing the list of files
- ;; --------------------------
- ;; By default, the list of current files is most recent first,
- ;; oldest last, with the exception that the files visible in the
- ;; current frame are put at the end of the list. A hook exists to
- ;; allow other functions to order the list. For example, if you add:
- ;;
- ;; (add-hook 'ido-make-buffer-list-hook 'ido-summary-buffers-to-end)
- ;;
- ;; then all files matching "Summary" are moved to the end of the
- ;; list. (I find this handy for keeping the INBOX Summary and so on
- ;; out of the way.) It also moves files matching "output\*$" to the
- ;; end of the list (these are created by AUCTeX when compiling.)
- ;; Other functions could be made available which alter the list of
- ;; matching files (either deleting or rearranging elements.)
- ;; Highlighting
- ;; ------------
- ;; The highlighting of matching items is controlled via ido-use-faces.
- ;; The faces used are ido-first-match, ido-only-match and
- ;; ido-subdir.
- ;; Coloring of the matching item was suggested by
- ;; Carsten Dominik (dominik@strw.leidenuniv.nl).
- ;; Replacement for read-buffer and read-file-name
- ;; ----------------------------------------------
- ;; ido-read-buffer and ido-read-file-name have been written to be drop
- ;; in replacements for the normal buffer and file name reading
- ;; functions `read-buffer' and `read-file-name'.
- ;; To use ido for all buffer and file selections in Emacs, customize the
- ;; variable `ido-everywhere'.
- ;; Using ido-like behavior in other Lisp packages
- ;; -----------------------------------------------
- ;; If you don't want to rely on the `ido-everywhere' functionality,
- ;; ido-read-buffer, ido-read-file-name, and ido-read-directory-name
- ;; can be used by other packages to read a buffer name, a file name,
- ;; or a directory name in the Ido way.
- ;;; Acknowledgments
- ;; Infinite amounts of gratitude goes to Stephen Eglen <stephen@cns.ed.ac.uk>
- ;; who wrote iswitch-buffer mode - from which I ripped off 99% of the code
- ;; for ido-switch-buffer and found the inspiration for ido-find-file.
- ;; The ido package would never have existed without his work.
- ;; Also thanks to Klaus Berndl, Rohit Namjoshi, Robert Fenk, Alex
- ;; Schroeder, Bill Benedetto, Stephen Eglen, and many others for bug
- ;; fixes and improvements.
- ;;; History
- ;; Since I discovered Stephen Eglen's excellent iswitchb package, I just
- ;; couldn't live without it, but once being addicted to switching buffers
- ;; with a minimum of keystrokes, I soon found that opening files in the
- ;; old-fashioned way was just too slow - so I decided to write a package
- ;; which could open files with the same speed and ease as iswitchb could
- ;; switch buffers.
- ;; I originally wrote a separate ifindf.el package based on a copy of
- ;; iswitchb.el, which did for opening files what iswitchb did for
- ;; switching buffers. Along the way, I corrected a few errors in
- ;; ifindf which could have found its way back into iswitchb, but since
- ;; most of the functionality of the two package was practically
- ;; identical, I decided that the proper thing to do was to merge my
- ;; ifindf package back into iswitchb.
- ;;
- ;; This is basically what ido (interactively do) is all about; but I
- ;; found it awkward to merge my changes into the "iswitchb-" namespace,
- ;; so I invented a common "ido-" namespace for the merged packages.
- ;;
- ;; This version is based on ido.el version 1.57 released on
- ;; gnu.emacs.sources adapted for Emacs 22.1 to use command remapping
- ;; and optionally hooking the read-buffer and read-file-name functions.
- ;;
- ;; Prefix matching was added by Klaus Berndl <klaus.berndl@sdm.de> based on
- ;; an idea of Yuji Minejima <ggb01164@nifty.ne.jp> and his mcomplete-package.
- ;;; Code:
- (defvar recentf-list)
- (require 'seq)
- ;;;; Options
- ;; These are some things you might want to change.
- (defun ido-fractionp (n)
- "Return t if N is a fraction."
- (and (numberp n) (> n 0.0) (<= n 1.0)))
- (defgroup ido nil
- "Switch between files using substrings."
- :group 'extensions
- :group 'convenience
- :version "22.1"
- :link '(emacs-commentary-link :tag "Commentary" "ido.el")
- :link '(emacs-library-link :tag "Lisp File" "ido.el")
- :link '(custom-manual "(ido) Top")
- :link '(info-link "(ido) Customization"))
- ;;;###autoload
- (defcustom ido-mode nil
- "Determines for which buffer/file Ido should be enabled.
- The following values are possible:
- - `buffer': Turn only on Ido buffer behavior (switching, killing,
- displaying...)
- - `file': Turn only on Ido file behavior (finding, writing, inserting...)
- - `both': Turn on Ido buffer and file behavior.
- - nil: Turn off any Ido switching.
- Setting this variable directly does not take effect;
- use either \\[customize] or the function `ido-mode'."
- :set #'(lambda (_symbol value)
- (ido-mode value))
- :initialize 'custom-initialize-default
- :require 'ido
- :link '(emacs-commentary-link "ido.el")
- :set-after '(ido-save-directory-list-file
- ;; This will clear ido-unc-hosts-cache, so set it
- ;; before loading history file.
- ido-unc-hosts)
- :type '(choice (const :tag "Turn on only buffer" buffer)
- (const :tag "Turn on only file" file)
- (const :tag "Turn on both buffer and file" both)
- (const :tag "Switch off all" nil))
- :group 'ido)
- (defcustom ido-case-fold case-fold-search
- "Non-nil if searching of buffer and file names should ignore case."
- :type 'boolean
- :group 'ido)
- (defcustom ido-ignore-buffers
- '("\\` ")
- "List of regexps or functions matching buffer names to ignore.
- For example, traditional behavior is not to list buffers whose names begin
- with a space, for which the regexp is `\\\\=` '. See the source file for
- example functions that filter buffer names."
- :type '(repeat (choice regexp function))
- :group 'ido)
- (defcustom ido-ignore-files
- '("\\`CVS/" "\\`#" "\\`.#" "\\`\\.\\./" "\\`\\./")
- "List of regexps or functions matching file names to ignore.
- For example, traditional behavior is not to list files whose names begin
- with a #, for which the regexp is `\\\\=`#'. See the source file for
- example functions that filter filenames."
- :type '(repeat (choice regexp function))
- :group 'ido)
- (defcustom ido-ignore-extensions t
- "Non-nil means ignore files in `completion-ignored-extensions' list."
- :type 'boolean
- :group 'ido)
- (defcustom ido-show-dot-for-dired nil
- "Non-nil means to always put . as the first item in file name lists.
- This allows the current directory to be opened immediately with `dired'."
- :type 'boolean
- :group 'ido)
- (defcustom ido-file-extensions-order nil
- "List of file extensions specifying preferred order of file selections.
- Each element is either a string with `.' as the first char, an empty
- string matching files without extension, or t which is the default order
- for files with an unlisted file extension."
- :type '(repeat (choice string
- (const :tag "Default order" t)))
- :group 'ido)
- (defcustom ido-ignore-directories
- '("\\`CVS/" "\\`\\.\\./" "\\`\\./")
- "List of regexps or functions matching sub-directory names to ignore."
- :type '(repeat (choice regexp function))
- :group 'ido)
- (defcustom ido-ignore-directories-merge nil
- "List of regexps or functions matching directory names to ignore during merge.
- Directory names matched by one of the regexps in this list are not inserted
- in merged file and directory lists."
- :type '(repeat (choice regexp function))
- :group 'ido)
- ;; Examples for setting the value of ido-ignore-buffers
- ;;(defun ido-ignore-c-mode (name)
- ;; "Ignore all c mode buffers -- example function for ido."
- ;; (with-current-buffer name
- ;; (derived-mode-p 'c-mode)))
- ;;
- ;;(setq ido-ignore-buffers '("\\` " ido-ignore-c-mode))
- ;; Examples for setting the value of ido-ignore-files
- ;;(setq ido-ignore-files '("\\` " "\\.c\\'" "\\.h\\'"))
- (defcustom ido-default-file-method 'raise-frame
- "How to visit a new file when using `ido-find-file'.
- Possible values:
- `selected-window' Show new file in selected window
- `other-window' Show new file in another window (same frame)
- `display' Display file in another window without selecting to it
- `other-frame' Show new file in another frame
- `maybe-frame' If a file is visible in another frame, prompt to ask if you
- you want to see the file in the same window of the current
- frame or in the other frame
- `raise-frame' If a file is visible in another frame, raise that
- frame; otherwise, visit the file in the same window"
- :type '(choice (const :tag "Visit in selected window" selected-window)
- (const :tag "Visit in other window" other-window)
- (const :tag "Display (no select) in other window" display)
- (const :tag "Visit in other frame" other-frame)
- (const :tag "Ask to visit in other frame" maybe-frame)
- (const :tag "Raise frame if already visited" raise-frame))
- :group 'ido)
- (defcustom ido-default-buffer-method 'raise-frame
- "How to switch to new buffer when using `ido-switch-buffer'.
- See `ido-default-file-method' for details."
- :type '(choice (const :tag "Show in selected window" selected-window)
- (const :tag "Show in other window" other-window)
- (const :tag "Display (no select) in other window" display)
- (const :tag "Show in other frame" other-frame)
- (const :tag "Ask to show in other frame" maybe-frame)
- (const :tag "Raise frame if already shown" raise-frame))
- :group 'ido)
- (defcustom ido-enable-flex-matching nil
- "Non-nil means that Ido will do flexible string matching.
- Flexible matching means that if the entered string does not
- match any item, any item containing the entered characters
- in the given sequence will match."
- :type 'boolean
- :group 'ido)
- (defcustom ido-enable-regexp nil
- "Non-nil means that Ido will do regexp matching.
- Value can be toggled within Ido using `ido-toggle-regexp'."
- :type 'boolean
- :group 'ido)
- (defcustom ido-enable-prefix nil
- "Non-nil means only match if the entered text is a prefix of file name.
- This behavior is like the standard Emacs completion.
- If nil, match if the entered text is an arbitrary substring.
- Value can be toggled within Ido using `ido-toggle-prefix'."
- :type 'boolean
- :group 'ido)
- (defcustom ido-enable-dot-prefix nil
- "Non-nil means to match leading dot as prefix.
- I.e. hidden files and buffers will match only if you type a dot
- as first char even if `ido-enable-prefix' is nil."
- :type 'boolean
- :group 'ido)
- ;; See http://debbugs.gnu.org/2042 for more info.
- (defcustom ido-buffer-disable-smart-matches t
- "Non-nil means not to re-order matches for buffer switching.
- By default, Ido arranges matches in the following order:
- full-matches > suffix matches > prefix matches > remaining matches
- which can get in the way for buffer switching."
- :version "24.3"
- :type 'boolean
- :group 'ido)
- (defcustom ido-confirm-unique-completion nil
- "Non-nil means that even a unique completion must be confirmed.
- This means that \\[ido-complete] must always be followed by \\[ido-exit-minibuffer]
- even when there is only one unique completion."
- :type 'boolean
- :group 'ido)
- (defcustom ido-cannot-complete-command 'ido-completion-help
- "Command run when `ido-complete' can't complete any more.
- The most useful values are `ido-completion-help', which pops up a
- window with completion alternatives, or `ido-next-match' or
- `ido-prev-match', which cycle the buffer list."
- :type 'function
- :group 'ido)
- (defcustom ido-record-commands t
- "Non-nil means that Ido will record commands in command history.
- Note that the non-Ido equivalent command is recorded."
- :type 'boolean
- :group 'ido)
- (defcustom ido-max-prospects 12
- "Upper limit of the prospect list if non-zero.
- Zero means no limit for the prospect list.
- For a long list of prospects, building the full list for the
- minibuffer can take a non-negligible amount of time; setting this
- variable reduces that time."
- :type 'integer
- :group 'ido)
- (defcustom ido-max-file-prompt-width 0.35
- "Upper limit of the prompt string.
- If value is an integer, it specifies the number of characters of
- the string.
- If value is a floating point number, it specifies a fraction of
- the frame width."
- :type '(choice
- (integer :tag "Characters" :value 20)
- (restricted-sexp :tag "Fraction of frame width"
- :value 0.35
- :match-alternatives (ido-fractionp)))
- :group 'ido)
- (defcustom ido-max-window-height nil
- "Non-nil specifies a value to override `max-mini-window-height'."
- :type '(choice
- (const :tag "Don't override" nil)
- (integer :tag "Number of lines" :value 1)
- (restricted-sexp
- :tag "Fraction of window height"
- :value 0.25
- :match-alternatives (ido-fractionp)))
- :group 'ido)
- (defcustom ido-enable-last-directory-history t
- "Non-nil means that Ido will remember latest selected directory names.
- See `ido-last-directory-list' and `ido-save-directory-list-file'."
- :type 'boolean
- :group 'ido)
- (defcustom ido-max-work-directory-list 50
- "Maximum number of working directories to record.
- This is the list of directories where files have most recently been opened.
- See `ido-work-directory-list' and `ido-save-directory-list-file'."
- :type 'integer
- :group 'ido)
- (defcustom ido-work-directory-list-ignore-regexps nil
- "List of regexps matching directories which should not be recorded.
- Directory names matched by one of the regexps in this list are not inserted in
- the `ido-work-directory-list' list."
- :type '(repeat regexp)
- :group 'ido)
- (defcustom ido-use-filename-at-point nil
- "Non-nil means that Ido shall look for a filename at point.
- May use `ffap-guesser' to guess whether text at point is a filename.
- If found, use that as the starting point for filename selection."
- :type '(choice
- (const :tag "Disabled" nil)
- (const :tag "Guess filename" guess)
- (other :tag "Use literal filename" t))
- :group 'ido)
- (defcustom ido-use-url-at-point nil
- "Non-nil means that ido shall look for a URL at point.
- If found, call `find-file-at-point' to visit it."
- :type 'boolean
- :group 'ido)
- (defcustom ido-enable-tramp-completion t
- "Non-nil means that Ido shall perform tramp method and server name completion.
- A tramp file name uses the following syntax: /method:user@host:filename."
- :type 'boolean
- :group 'ido)
- (defcustom ido-record-ftp-work-directories t
- "Non-nil means record FTP file names in the work directory list."
- :type 'boolean
- :group 'ido)
- (defcustom ido-merge-ftp-work-directories nil
- "If nil, merging ignores FTP file names in the work directory list."
- :type 'boolean
- :group 'ido)
- (defcustom ido-cache-ftp-work-directory-time 1.0
- "Maximum time to cache contents of an FTP directory (in hours).
- \\<ido-file-completion-map>
- Use \\[ido-reread-directory] in prompt to refresh list.
- If zero, FTP directories are not cached."
- :type 'number
- :group 'ido)
- (defcustom ido-slow-ftp-hosts nil
- "List of slow FTP hosts where Ido prompting should not be used.
- If an FTP host is on this list, Ido automatically switches to the non-Ido
- equivalent function, e.g. `find-file' rather than `ido-find-file'."
- :type '(repeat string)
- :group 'ido)
- (defcustom ido-slow-ftp-host-regexps nil
- "List of regexps matching slow FTP hosts (see `ido-slow-ftp-hosts')."
- :type '(repeat regexp)
- :group 'ido)
- (defvar ido-unc-hosts-cache t
- "Cached value from the function `ido-unc-hosts'.")
- (defcustom ido-unc-hosts nil
- "List of known UNC host names to complete after initial //.
- If value is a function, that function is called to search network for
- hosts on first use of UNC path."
- :type '(choice (repeat :tag "List of UNC host names" string)
- (function-item :tag "Use `NET VIEW'"
- :value ido-unc-hosts-net-view)
- (function :tag "Your own function"))
- :set #'(lambda (symbol value)
- (set symbol value)
- (setq ido-unc-hosts-cache t))
- :group 'ido)
- (defcustom ido-downcase-unc-hosts t
- "Non-nil if UNC host names should be downcased."
- :type 'boolean
- :group 'ido)
- (defcustom ido-ignore-unc-host-regexps nil
- "List of regexps matching UNC hosts to ignore.
- Case is ignored if `ido-downcase-unc-hosts' is set."
- :type '(repeat regexp)
- :group 'ido)
- (defcustom ido-cache-unc-host-shares-time 8.0
- "Maximum time to cache shares of an UNC host (in hours).
- \\<ido-file-completion-map>
- Use \\[ido-reread-directory] in prompt to refresh list.
- If zero, UNC host shares are not cached."
- :type 'number
- :group 'ido)
- (defcustom ido-max-work-file-list 10
- "Maximum number of names of recently opened files to record.
- This is the list of the file names (sans directory) which have most recently
- been opened. See `ido-work-file-list' and `ido-save-directory-list-file'."
- :type 'integer
- :group 'ido)
- (defcustom ido-work-directory-match-only t
- "Non-nil means to skip non-matching directories in the directory history.
- When some text is already entered at the `ido-find-file' prompt, using
- \\[ido-prev-work-directory] or \\[ido-next-work-directory] will skip directories
- without any matching entries."
- :type 'boolean
- :group 'ido)
- (defcustom ido-auto-merge-work-directories-length 0
- "Automatically switch to merged work directories during file name input.
- The value is number of characters to type before switching to merged mode.
- If zero, the switch happens when no matches are found in the current directory.
- Automatic merging is disabled if the value is negative."
- :type 'integer
- :group 'ido)
- (defcustom ido-auto-merge-delay-time 0.70
- "Delay in seconds to wait for more input before doing auto merge."
- :type 'number
- :group 'ido)
- (defcustom ido-auto-merge-inhibit-characters-regexp "[][*?~]"
- "Regexp matching characters which should inhibit automatic merging.
- When a (partial) file name matches this regexp, merging is inhibited."
- :type 'regexp
- :group 'ido)
- (defcustom ido-merged-indicator "^"
- "The string appended to first choice if it has multiple directory choices."
- :type 'string
- :group 'ido)
- (defcustom ido-max-dir-file-cache 100
- "Maximum number of working directories to be cached.
- \\<ido-file-completion-map>
- This is the size of the cache of `file-name-all-completions' results.
- Each cache entry is time stamped with the modification time of the
- directory. Some systems, like Windows, have unreliable directory
- modification times, so you may choose to disable caching on such
- systems, or explicitly refresh the cache contents using the command
- `ido-reread-directory' command (\\[ido-reread-directory]) in the minibuffer.
- See also `ido-dir-file-cache' and `ido-save-directory-list-file'."
- :type 'integer
- :group 'ido)
- (defcustom ido-max-directory-size nil
- "Maximum size (in bytes) for directories to use Ido completion.
- \\<ido-completion-map>
- If you enter a directory with a size larger than this size, Ido will
- not provide the normal completion. To show the completions, use \\[ido-toggle-ignore]."
- :type '(choice (const :tag "No limit" nil)
- (integer :tag "Size in bytes" 30000))
- :group 'ido)
- (defcustom ido-rotate-file-list-default nil
- "Non-nil means that Ido will always rotate file list to get default in front."
- :type 'boolean
- :group 'ido)
- (defcustom ido-enter-matching-directory 'only
- "Additional methods to enter sub-directory of first/only matching item.
- If value is `first', enter first matching sub-directory when typing a slash.
- If value is `only', typing a slash only enters the sub-directory if it is
- the only matching item.
- If value is t, automatically enter a sub-directory when it is the only
- matching item, even without typing a slash."
- :type '(choice (const :tag "Never" nil)
- (const :tag "Slash enters first directory" first)
- (const :tag "Slash enters first and only directory" only)
- (other :tag "Always enter unique directory" t))
- :group 'ido)
- (defcustom ido-create-new-buffer 'prompt
- "Specify whether a new buffer is created if no buffer matches substring.
- Choices are `always' to create new buffers unconditionally, `prompt' to
- ask user whether to create buffer, or `never' to never create new buffer."
- :type '(choice (const always)
- (const prompt)
- (const never))
- :group 'ido)
- (defcustom ido-setup-hook nil
- "Hook run after the Ido variables and keymap have been setup.
- The dynamic variable `ido-cur-item' contains the current type of item that
- is read by Ido; possible values are file, dir, buffer, and list.
- Additional keys can be defined in `ido-completion-map'."
- :type 'hook
- :group 'ido)
- (defcustom ido-separator nil
- "String used by Ido to separate the alternatives in the minibuffer."
- :type '(choice string (const nil))
- :group 'ido)
- (make-obsolete-variable 'ido-separator
- "set 3rd element of `ido-decorations' instead." nil)
- (defcustom ido-decorations '("{" "}" " | " " | ..." "[" "]" " [No match]"
- " [Matched]" " [Not readable]" " [Too big]" " [Confirm]")
- "List of strings used by Ido to display the alternatives in the minibuffer.
- There are between 11 and 13 elements in this list:
- 1st and 2nd elements are used as brackets around the prospect list,
- 3rd element is the separator between prospects (ignored if
- `ido-separator' is set),
- 4th element is the string inserted at the end of a truncated list of prospects,
- 5th and 6th elements are used as brackets around the common match string which
- can be completed using TAB,
- 7th element is the string displayed when there are no matches, and
- 8th element is displayed if there is a single match (and faces are not used),
- 9th element is displayed when the current directory is non-readable,
- 10th element is displayed when directory exceeds `ido-max-directory-size',
- 11th element is displayed to confirm creating new file or buffer.
- 12th and 13th elements (if present) are used as brackets around the sole
- remaining completion. If absent, elements 5 and 6 are used instead."
- :type '(repeat string)
- :group 'ido)
- (defcustom ido-use-virtual-buffers nil
- "If non-nil, refer to past (\"virtual\") buffers as well as existing ones.
- The options are:
- nil: Do not use virtual buffers.
- t: Always use virtual buffers.
- auto: Use virtual buffers if the current input matches no existing buffer.
- Essentially it works as follows: Say you are visiting a file and
- the buffer gets cleaned up by midnight.el. Later, you want to
- switch to that buffer, but find it's no longer open. With virtual
- buffers enabled, the buffer name stays in the buffer list (using
- the `ido-virtual' face, and always at the end), and if you select
- it, it opens the file back up again. This allows you to think
- less about whether recently opened files are still open or not.
- Most of the time you can quit Emacs, restart, and then switch to
- a file buffer that was previously open as if it still were.
- This feature relies upon the `recentf' package, which will be
- enabled if this variable is configured to a non-nil value."
- :version "24.1"
- :type '(choice (const :tag "Always" t)
- (const :tag "Automatic" auto)
- (const :tag "Never" nil))
- :group 'ido)
- (defcustom ido-use-faces t
- "Non-nil means use Ido faces to highlighting first match, only match and
- subdirs in the alternatives."
- :type 'boolean
- :group 'ido)
- (defface ido-first-match '((t :weight bold))
- "Face used by Ido for highlighting first match."
- :group 'ido)
- (defface ido-only-match '((((class color))
- :foreground "ForestGreen")
- (t :slant italic))
- "Face used by Ido for highlighting only match."
- :group 'ido)
- (defface ido-subdir '((((min-colors 88) (class color))
- :foreground "red1")
- (((class color))
- :foreground "red")
- (t :underline t))
- "Face used by Ido for highlighting subdirs in the alternatives."
- :group 'ido)
- (defface ido-virtual '((t :inherit font-lock-builtin-face))
- "Face used by Ido for matching virtual buffer names."
- :version "24.1"
- :group 'ido)
- (defface ido-indicator '((((min-colors 88) (class color))
- :foreground "yellow1" :background "red1" :width condensed)
- (((class color))
- :foreground "yellow" :background "red" :width condensed)
- (t :inverse-video t))
- "Face used by Ido for highlighting its indicators."
- :group 'ido)
- (defface ido-incomplete-regexp
- '((t :inherit font-lock-warning-face))
- "Ido face for indicating incomplete regexps."
- :group 'ido)
- (defcustom ido-make-file-list-hook nil
- "List of functions to run when the list of matching files is created.
- Each function on the list may modify the dynamically bound variable
- `ido-temp-list' which contains the current list of matching files."
- :type 'hook
- :group 'ido)
- (defcustom ido-make-dir-list-hook nil
- "List of functions to run when the list of matching directories is created.
- Each function on the list may modify the dynamically bound variable
- `ido-temp-list' which contains the current list of matching directories."
- :type 'hook
- :group 'ido)
- (defcustom ido-make-buffer-list-hook nil
- "List of functions to run when the list of matching buffers is created.
- Each function on the list may modify the dynamically bound variable
- `ido-temp-list' which contains the current list of matching buffer names."
- :type 'hook
- :group 'ido)
- (defcustom ido-rewrite-file-prompt-functions nil
- "List of functions to run when the find-file prompt is created.
- Each function on the list may modify the following dynamically bound
- variables:
- dirname - the (abbreviated) directory name
- to be modified by the hook functions
- max-width - the max width of the resulting dirname; nil means no limit
- prompt - the basic prompt (e.g. \"Find File: \")
- literal - the string shown if doing \"literal\" find; set to nil to omit
- vc-off - the string shown if version control is inhibited; set to nil to omit
- prefix - either nil or a fixed prefix for the dirname
- The following variables are available, but should not be changed:
- `ido-current-directory' - the unabbreviated directory name
- item - equals `file' or `dir' depending on the current mode."
- :type 'hook
- :group 'ido)
- (defvar ido-rewrite-file-prompt-rules nil
- "Alist of rewriting rules for directory names in Ido prompts.
- A list of elements of the form (FROM . TO) or (FROM . FUNC), each
- meaning to rewrite the directory name if matched by FROM by either
- substituting the matched string by TO or calling the function FUNC
- with the current directory name as its only argument and using the
- return value as the new directory name. In addition, each FUNC may
- also modify the dynamic variables described for the variable
- `ido-rewrite-file-prompt-functions'.")
- (defcustom ido-completion-buffer "*Ido Completions*"
- "Name of completion buffer used by Ido.
- Set to nil to disable completion buffers popping up."
- :type 'string
- :group 'ido)
- (defcustom ido-completion-buffer-all-completions nil
- "Non-nil means to show all completions in completion buffer.
- Otherwise, only the current list of matches is shown."
- :type 'boolean
- :group 'ido)
- (defcustom ido-all-frames 'visible
- "Argument to pass to `walk-windows' when Ido is finding buffers.
- See documentation of `walk-windows' for useful values."
- :type '(choice (const :tag "Selected frame only" nil)
- (const :tag "All existing frames" t)
- (const :tag "All visible frames" visible)
- (const :tag "All frames on this terminal" 0))
- :group 'ido)
- (defcustom ido-minibuffer-setup-hook nil
- "Ido-specific customization of minibuffer setup.
- This hook is run during minibuffer setup if Ido is active.
- It is intended for use in customizing Ido for interoperation
- with other packages. For instance:
- (add-hook \\='ido-minibuffer-setup-hook
- (lambda () (setq-local max-mini-window-height 3)))
- will constrain Emacs to a maximum minibuffer height of 3 lines when
- Ido is running. Copied from `icomplete-minibuffer-setup-hook'."
- :type 'hook
- :group 'ido)
- (defcustom ido-save-directory-list-file
- (locate-user-emacs-file "ido.last" ".ido.last")
- "File in which the Ido state is saved between invocations.
- Variables stored are: `ido-last-directory-list', `ido-work-directory-list',
- `ido-work-file-list', and `ido-dir-file-cache'.
- Must be set before enabling Ido mode."
- :version "24.4" ; added locate-user-emacs-file
- :type 'string
- :group 'ido)
- (defcustom ido-read-file-name-as-directory-commands '()
- "List of commands which use `read-file-name' to read a directory name.
- When `ido-everywhere' is non-nil, the commands in this list will read
- the directory using `ido-read-directory-name'."
- :type '(repeat symbol)
- :group 'ido)
- (defcustom ido-read-file-name-non-ido '()
- "List of commands which shall not read file names the Ido way.
- When `ido-everywhere' is non-nil, the commands in this list will read
- the file name using normal `read-file-name' style."
- :type '(repeat symbol)
- :group 'ido)
- (defcustom ido-before-fallback-functions '()
- "List of functions to call before calling a fallback command.
- The fallback command is passed as an argument to the functions."
- :type 'hook
- :group 'ido)
- ;;;; Keymaps
- (defvar ido-common-completion-map
- (let ((map (make-sparse-keymap)))
- (set-keymap-parent map minibuffer-local-map)
- (define-key map "\C-a" 'ido-toggle-ignore)
- (define-key map "\C-c" 'ido-toggle-case)
- (define-key map "\C-e" 'ido-edit-input)
- (define-key map "\t" 'ido-complete)
- (define-key map " " 'ido-complete-space)
- (define-key map "\C-j" 'ido-select-text)
- (define-key map "\C-m" 'ido-exit-minibuffer)
- (define-key map "\C-p" 'ido-toggle-prefix)
- (define-key map "\C-r" 'ido-prev-match)
- (define-key map "\C-s" 'ido-next-match)
- (define-key map [?\C-.] 'ido-next-match)
- (define-key map [?\C-,] 'ido-prev-match)
- (define-key map "\C-t" 'ido-toggle-regexp)
- (define-key map "\C-z" 'ido-undo-merge-work-directory)
- (define-key map [(control ?\s)] 'ido-restrict-to-matches)
- (define-key map [(meta ?\s)] 'ido-take-first-match)
- (define-key map [(control ?@)] 'ido-restrict-to-matches)
- (define-key map [right] 'ido-next-match)
- (define-key map [left] 'ido-prev-match)
- (define-key map "?" 'ido-completion-help)
- (define-key map "\C-b" 'ido-magic-backward-char)
- (define-key map "\C-f" 'ido-magic-forward-char)
- (define-key map "\C-d" 'ido-magic-delete-char)
- map)
- "Keymap for all Ido commands.")
- (defvar ido-file-dir-completion-map
- (let ((map (make-sparse-keymap)))
- (set-keymap-parent map ido-common-completion-map)
- (define-key map "\C-x\C-b" 'ido-enter-switch-buffer)
- (define-key map "\C-x\C-f" 'ido-fallback-command)
- (define-key map "\C-x\C-d" 'ido-enter-dired)
- (define-key map [down] 'ido-next-match-dir)
- (define-key map [up] 'ido-prev-match-dir)
- (define-key map [(meta up)] 'ido-prev-work-directory)
- (define-key map [(meta down)] 'ido-next-work-directory)
- (define-key map [backspace] 'ido-delete-backward-updir)
- (define-key map "\d" 'ido-delete-backward-updir)
- (define-key map [remap delete-backward-char] 'ido-delete-backward-updir) ; BS
- (define-key map [remap backward-kill-word] 'ido-delete-backward-word-updir) ; M-DEL
- (define-key map [(control backspace)] 'ido-up-directory)
- (define-key map "\C-l" 'ido-reread-directory)
- (define-key map [(meta ?d)] 'ido-wide-find-dir-or-delete-dir)
- (define-key map [(meta ?b)] 'ido-push-dir)
- (define-key map [(meta ?v)] 'ido-push-dir-first)
- (define-key map [(meta ?f)] 'ido-wide-find-file-or-pop-dir)
- (define-key map [(meta ?k)] 'ido-forget-work-directory)
- (define-key map [(meta ?m)] 'ido-make-directory)
- (define-key map [(meta ?n)] 'ido-next-work-directory)
- (define-key map [(meta ?o)] 'ido-prev-work-file)
- (define-key map [(meta control ?o)] 'ido-next-work-file)
- (define-key map [(meta ?p)] 'ido-prev-work-directory)
- (define-key map [(meta ?s)] 'ido-merge-work-directories)
- map)
- "Keymap for Ido file and directory commands.")
- (defvar ido-file-completion-map
- (let ((map (make-sparse-keymap)))
- (set-keymap-parent map ido-file-dir-completion-map)
- (define-key map "\C-k" 'ido-delete-file-at-head)
- (define-key map "\C-o" 'ido-copy-current-word)
- (define-key map "\C-w" 'ido-copy-current-file-name)
- (define-key map [(meta ?l)] 'ido-toggle-literal)
- map)
- "Keymap for Ido file commands.")
- (defvar ido-buffer-completion-map
- (let ((map (make-sparse-keymap)))
- (set-keymap-parent map ido-common-completion-map)
- (define-key map "\C-x\C-f" 'ido-enter-find-file)
- (define-key map "\C-x\C-b" 'ido-fallback-command)
- (define-key map "\C-k" 'ido-kill-buffer-at-head)
- (define-key map [?\C-\S-b] 'ido-bury-buffer-at-head)
- (define-key map "\C-o" 'ido-toggle-virtual-buffers)
- map)
- "Keymap for Ido buffer commands.")
- ;;;; Persistent variables
- (defvar ido-file-history nil
- "History of files selected using `ido-find-file'.")
- (defvar ido-buffer-history nil
- "History of buffers selected using `ido-switch-buffer'.")
- (defvar ido-last-directory-list nil
- "List of last selected directory names.
- See `ido-enable-last-directory-history' for details.")
- (defvar ido-work-directory-list nil
- "List of actual working directory names.
- The current directory is inserted at the front of this list whenever a
- file is opened with `ido-find-file' and family.")
- (defvar ido-work-file-list nil
- "List of actual work file names.
- Opening a file with `ido-find-file' and similar functions
- inserts the current file name (relative to its containing directory)
- at the front of this list.")
- (defvar ido-dir-file-cache nil
- "List of `file-name-all-completions' results.
- Each element in the list is of the form (DIR (MTIME) FILE...).")
- (defvar ido-ignore-item-temp-list nil
- "List of items to ignore in current Ido invocation.
- Intended to be let-bound by functions which call Ido repeatedly.
- Should never be set permanently.")
- ;;;; Temporary storage
- (defvar ido-completion-map nil
- "Currently active keymap for Ido commands.")
- (defvar ido-eoinput 1
- "Point where minibuffer input ends and completion info begins.
- Copied from `icomplete-eoinput'.")
- (make-variable-buffer-local 'ido-eoinput)
- (defvar ido-common-match-string nil
- "Stores the string that is common to all matching files.")
- (defvar ido-rescan nil
- "Non-nil means we need to regenerate the list of matching items.")
- (defvar ido-rotate nil
- "Non-nil means we are rotating list of matches.")
- (defvar ido-text nil
- "Stores the user's string as it is typed in.")
- (defvar ido-text-init nil
- "The initial string for the user's string it is typed in.")
- (defvar ido-input-stack nil
- "Stores the user's strings when user hits M-b/M-f.")
- (defvar ido-matches nil
- "List of files currently matching `ido-text'.")
- (defvar ido-report-no-match t
- "Report \"[No Match]\" when no completions matches `ido-text'.")
- (defvar ido-exit nil
- "Flag to monitor how `ido-find-file' exits.
- If equal to `takeprompt', we use the prompt as the file name to be
- selected.")
- (defvar ido-current-directory nil
- "Current directory for `ido-find-file'.")
- (defvar ido-auto-merge-timer nil
- "Delay timer for auto merge.")
- (defvar ido-use-mycompletion-depth 0
- "Non-nil means use Ido completion feedback.
- Is set by Ido functions to the current `minibuffer-depth',
- so that it doesn't interfere with other minibuffer usage.")
- (defvar ido-incomplete-regexp nil
- "Non-nil if an incomplete regexp is entered.")
- (defvar ido-initial-position nil
- "Non-nil means to explicitly cursor on entry to minibuffer.
- Value is an integer which is number of chars to right of prompt.")
- (defvar ido-virtual-buffers nil
- "List of virtual buffers, that is, past visited files.
- This is a copy of `recentf-list', pared down and with faces applied.
- Only used if `ido-use-virtual-buffers' is non-nil.")
- ;;;; Variables with dynamic bindings.
- ;; These are declared here to keep the byte compiler quiet.
- ;; Stores the current ido item type ('file, 'dir, 'buffer, or 'list).
- (defvar ido-cur-item)
- ;; Stores the current default item.
- (defvar ido-default-item)
- ;; Stores the current list of items that will be searched through.
- ;; The list is ordered, so that the most interesting item comes first,
- ;; although by default, the files visible in the current frame are put
- ;; at the end of the list. Created by `ido-make-item-list'.
- (defvar ido-cur-list)
- ;; Stores the choice list for ido-completing-read
- (defvar ido-choice-list)
- ;; Stores the list of items which are ignored when building
- ;; `ido-cur-list'. It is in no specific order.
- (defvar ido-ignored-list)
- ;; Remember if current directory is non-readable (so we cannot do completion).
- (defvar ido-directory-nonreadable)
- ;; Remember if current directory is 'huge' (so we don't want to do completion).
- (defvar ido-directory-too-big)
- ;; Keep current item list if non-nil.
- (defvar ido-keep-item-list)
- ;; Process ido-ignore-* lists.
- (defvar ido-process-ignore-lists)
- ;; Don't process ido-ignore- lists once.
- (defvar ido-process-ignore-lists-inhibit)
- ;; Is ido using virtual buffers?
- (defvar ido-enable-virtual-buffers)
- ;; Buffer from which ido was entered.
- (defvar ido-entry-buffer)
- ;; Non-nil if matching file must be selected.
- (defvar ido-require-match)
- ;; Non-nil if we should add [confirm] to prompt
- (defvar ido-show-confirm-message)
- ;; Stores a temporary version of the file list being created.
- (defvar ido-temp-list)
- ;; Non-nil if default list element should be rotated into place.
- (defvar ido-rotate-temp)
- ;; Stores current index in ido-work-directory-list.
- (defvar ido-work-directory-index)
- ;; Stores current index in ido-work-file-list.
- (defvar ido-work-file-index)
- ;; Set when merged work directory list is in use.
- (defvar ido-use-merged-list)
- ;; Set when merged work directory list not yet built.
- (defvar ido-try-merged-list)
- ;; Saved state prior to last work directory merge.
- ;; Value is a list (ido-text dir cur-list ignored-list matches).
- (defvar ido-pre-merge-state)
- ;; Original value of vc-handled-backends for use in ido-toggle-vc.
- (defvar ido-saved-vc-hb)
- ;; Stores temporary state of literal find file.
- (defvar ido-find-literal)
- ;; Set to 'ignore to inhibit switching between find-file/switch-buffer.
- (defvar ido-context-switch-command)
- ;; Dynamically bound in ido-read-internal.
- (defvar ido-completing-read)
- ;;; FUNCTIONS
- (defun ido-active (&optional merge)
- (if merge
- ido-use-merged-list
- (and (boundp 'ido-completing-read)
- (or (featurep 'xemacs)
- (= ido-use-mycompletion-depth (minibuffer-depth))))))
- (defvar ido-trace-enable nil)
- (defun ido-trace (p &optional s retval)
- (if ido-trace-enable
- (let ((b (get-buffer-create " *IDO Trace*"))
- (deactivate-mark deactivate-mark))
- (save-excursion
- (save-restriction
- (set-buffer b)
- (insert p ": " (if (stringp s) s (format "%S" s)) "\n")))))
- retval)
- (defun ido-toggle-trace (arg)
- (interactive "P")
- (setq ido-trace-enable (or arg (not ido-trace-enable)))
- (if ido-trace-enable
- (message "IDO trace on"))
- (let ((b (get-buffer " *IDO Trace*")))
- (if b
- (if ido-trace-enable
- (kill-buffer b)
- (pop-to-buffer b t t)
- (setq truncate-lines t)))))
- (defun ido-local-file-exists-p (file)
- "Tell if FILE exists locally."
- (let (file-name-handler-alist)
- (file-exists-p file)))
- (defun ido-unc-hosts (&optional query)
- "Return list of UNC host names."
- (let ((hosts
- (cond
- ((listp ido-unc-hosts)
- ido-unc-hosts) ;; static list or nil
- ((listp ido-unc-hosts-cache)
- ido-unc-hosts-cache) ;; result of net search
- ((and query (fboundp ido-unc-hosts))
- (message (propertize "Searching for UNC hosts..." 'face 'highlight))
- (setq ido-unc-hosts-cache (funcall ido-unc-hosts))
- (message nil)
- ido-unc-hosts-cache)
- (query
- (setq ido-unc-hosts-cache nil))
- (t (fboundp ido-unc-hosts)))))
- (when query
- (let ((case-fold-search ido-downcase-unc-hosts)
- res host re-list re)
- (while hosts
- (setq host (car hosts)
- hosts (cdr hosts)
- re-list (and ido-process-ignore-lists
- ido-ignore-unc-host-regexps))
- (while re-list
- (setq re (car re-list)
- re-list (cdr re-list))
- (if (string-match re host)
- (setq re-list nil
- host nil)))
- (when host
- (when ido-downcase-unc-hosts
- (setq host (downcase host)))
- (setq res (cons host res))))
- (setq hosts (sort res #'string<))))
- hosts))
- (defun ido-unc-hosts-net-view ()
- "Query network for list of UNC host names using `NET VIEW'."
- (let (hosts)
- (with-temp-buffer
- (shell-command "net view" t)
- (goto-char (point-min))
- (while (re-search-forward "^\\\\\\\\\\([[:graph:]]+\\)" nil t)
- (setq hosts (cons (match-string 1) hosts))))
- hosts))
- (defun ido-is-tramp-root (&optional dir)
- (and ido-enable-tramp-completion
- (string-match "\\`/[^/]+[@:]\\'"
- (or dir ido-current-directory))))
- (defun ido-is-unc-root (&optional dir)
- (and (ido-unc-hosts)
- (string-equal "//"
- (or dir ido-current-directory))))
- (defun ido-is-unc-host (&optional dir)
- (and (ido-unc-hosts)
- (string-match "\\`//[^/]+/\\'"
- (or dir ido-current-directory))))
- (defun ido-is-root-directory (&optional dir)
- (setq dir (or dir ido-current-directory))
- (or
- (string-equal "/" dir)
- (and (memq system-type '(windows-nt ms-dos))
- (string-match "\\`[a-zA-Z]:[/\\]\\'" dir))
- (if ido-enable-tramp-completion
- (ido-is-tramp-root dir)
- (string-match "\\`/[^:/][^:/]+:\\'" dir))))
- (defun ido-is-ftp-directory (&optional dir)
- (string-match
- (if ido-enable-tramp-completion
- ;; like tramp-file-name-regexp-unified, but doesn't match single drive letters
- "\\`/[^/:][^/:]+:"
- "\\`/[^/:][^/:]+:/")
- (or dir ido-current-directory)))
- (defun ido-is-slow-ftp-host (&optional dir)
- (and (or ido-slow-ftp-hosts ido-slow-ftp-host-regexps)
- (setq dir (or dir ido-current-directory))
- ;; (featurep 'ange-ftp)
- ;; (ange-ftp-ftp-name dir)
- (string-match
- (if ido-enable-tramp-completion
- "\\`/\\([^/]+[@:]\\)*\\([^@/:][^@/:]+\\):"
- "\\`/\\([^/:]*@\\)?\\([^@/:][^@/:]+\\):/")
- dir)
- (let ((host (substring dir (match-beginning 2) (match-end 2))))
- (or (member host ido-slow-ftp-hosts)
- (let ((re ido-slow-ftp-host-regexps))
- (while (and re (not (string-match (car re) host)))
- (setq re (cdr re)))
- re)))))
- (defun ido-time-stamp (&optional time)
- ;; Time is a floating point number (fractions of 1 hour)
- (/ (float-time time) 3600))
- (defun ido-cache-ftp-valid (&optional time)
- (and (numberp ido-cache-ftp-work-directory-time)
- (> ido-cache-ftp-work-directory-time 0)
- (or (not time)
- (< (- (ido-time-stamp) time) ido-cache-ftp-work-directory-time))))
- (defun ido-cache-unc-valid (&optional time)
- (and (numberp ido-cache-unc-host-shares-time)
- (> ido-cache-unc-host-shares-time 0)
- (or (not time)
- (< (- (ido-time-stamp) time) ido-cache-unc-host-shares-time))))
- (defun ido-may-cache-directory (&optional dir)
- (setq dir (or dir ido-current-directory))
- (cond
- ((and (ido-is-root-directory dir)
- (or ido-enable-tramp-completion
- (memq system-type '(windows-nt ms-dos))))
- nil)
- ((ido-is-unc-host dir)
- (ido-cache-unc-valid))
- ((ido-is-ftp-directory dir)
- (ido-cache-ftp-valid))
- ((ido-directory-too-big-p dir)
- nil)
- (t t)))
- (defun ido-pp (list &optional sep)
- (let ((print-level nil) (eval-expression-print-level nil)
- (print-length nil) (eval-expression-print-length nil))
- (insert "\n;; ----- " (symbol-name list) " -----\n(\n ")
- (setq list (symbol-value list))
- (while list
- (let* ((elt (car list))
- (s (if (consp elt) (car elt) elt)))
- (if (and (stringp s) (= (length s) 0))
- (setq s nil))
- (if s
- (prin1 elt (current-buffer)))
- (if (and (setq list (cdr list)) s)
- (insert (or sep "\n ")))))
- (insert "\n)\n")))
- (defun ido-save-history ()
- "Save Ido history and cache information between sessions."
- (interactive)
- (when (and ido-last-directory-list ido-save-directory-list-file)
- (let ((buf (get-buffer-create " *ido session*"))
- (version-control 'never))
- (unwind-protect
- (with-current-buffer buf
- (erase-buffer)
- (insert ";;; -*- coding: utf-8 -*-\n")
- (setq buffer-file-coding-system 'utf-8)
- (ido-pp 'ido-last-directory-list)
- (ido-pp 'ido-work-directory-list)
- (ido-pp 'ido-work-file-list)
- (ido-pp 'ido-dir-file-cache "\n\n ")
- (if (listp ido-unc-hosts-cache)
- (ido-pp 'ido-unc-hosts-cache)
- (insert "\n;; ----- ido-unc-hosts-cache -----\nt\n"))
- (write-file ido-save-directory-list-file nil))
- (kill-buffer buf)))))
- (defun ido-load-history (&optional arg)
- "Load Ido history and cache information from previous session.
- With prefix argument, reload history unconditionally."
- (interactive "P")
- (if (or arg (and ido-save-directory-list-file (not ido-last-directory-list)))
- (let ((file (expand-file-name ido-save-directory-list-file))
- buf)
- (when (file-readable-p file)
- (setq buf (get-buffer-create " *ido session*"))
- (unwind-protect
- (with-current-buffer buf
- (erase-buffer)
- (insert-file-contents file)
- (condition-case nil
- (setq ido-last-directory-list (read (current-buffer))
- ido-work-directory-list (read (current-buffer))
- ido-work-file-list (read (current-buffer))
- ido-dir-file-cache (read (current-buffer))
- ido-unc-hosts-cache (read (current-buffer)))
- (error nil)))
- (kill-buffer buf)))))
- (ido-wash-history))
- (defun ido-wash-history ()
- "Clean-up Ido history and cache information.
- Removes badly formatted data and ignored directories."
- (interactive)
- ;; Check format of each of our lists, discard bogus elements
- (setq ido-last-directory-list
- (and (listp ido-last-directory-list)
- (let ((l ido-last-directory-list) r)
- (while l
- (if (and (consp (car l))
- (stringp (car (car l)))
- (stringp (cdr (car l))))
- (setq r (cons (car l) r)))
- (setq l (cdr l)))
- (nreverse r))))
- (setq ido-work-directory-list
- (and (listp ido-work-directory-list)
- (let ((l ido-work-directory-list) r)
- (while l
- (if (and (stringp (car l))
- (or ido-record-ftp-work-directories
- (not (ido-is-ftp-directory (car l)))))
- (setq r (cons (car l) r)))
- (setq l (cdr l)))
- (nreverse r))))
- (setq ido-work-file-list
- (and (listp ido-work-file-list)
- (let ((l ido-work-file-list) r)
- (while l
- (if (stringp (car l))
- (setq r (cons (car l) r)))
- (setq l (cdr l)))
- (nreverse r))))
- (setq ido-dir-file-cache
- (and (listp ido-dir-file-cache)
- (let ((l ido-dir-file-cache) r)
- (while l
- (if (and (listp (car l))
- (> (length (car l)) 2)
- (let ((dir (car (car l)))
- (time (car (cdr (car l))))
- (files (cdr (cdr (car l)))))
- (and
- (stringp dir)
- (consp time)
- (cond
- ((integerp (car time))
- (and (/= (car time) 0)
- (integerp (car (cdr time)))
- (/= (car (cdr time)) 0)
- (ido-may-cache-directory dir)))
- ((eq (car time) 'ftp)
- (and (numberp (cdr time))
- (ido-is-ftp-directory dir)
- (ido-cache-ftp-valid (cdr time))))
- ((eq (car time) 'unc)
- (and (numberp (cdr time))
- (ido-is-unc-host dir)
- (ido-cache-unc-valid (cdr time))))
- (t nil))
- (let ((s files) (ok t))
- (while s
- (if (stringp (car s))
- (setq s (cdr s))
- (setq s nil ok nil)))
- ok))))
- (setq r (cons (car l) r)))
- (setq l (cdr l)))
- (nreverse r))))
- ;; Remove ignored directories from work directory list
- ;; according to ido-work-directory-list-ignore-regexps
- (if ido-work-directory-list
- (let ((dirs (reverse ido-work-directory-list)))
- (setq ido-work-directory-list nil)
- (while dirs
- (ido-record-work-directory (car dirs))
- (setq dirs (cdr dirs)))))
- ;; Get rid of text properties
- (let ((l ido-last-directory-list) e)
- (while l
- (setq e (car l) l (cdr l))
- (set-text-properties 0 (length (car e)) nil (car e))
- (set-text-properties 0 (length (cdr e)) nil (cdr e))))
- (let ((l ido-work-directory-list) e)
- (while l
- (setq e (car l) l (cdr l))
- (set-text-properties 0 (length e) nil e)))
- (let ((l ido-work-file-list) e)
- (while l
- (setq e (car l) l (cdr l))
- (set-text-properties 0 (length e) nil e)))
- (let ((l ido-dir-file-cache) e d)
- (while l
- (setq e (car l) l (cdr l))
- (if (listp e)
- (while e
- (setq d (car e) e (cdr e))
- (if (not (consp d))
- (set-text-properties 0 (length d) nil d)))))))
- (defun ido-kill-emacs-hook ()
- ;; ido kill emacs hook
- (ido-save-history))
- (defun ido-common-initialization ()
- (add-hook 'minibuffer-setup-hook 'ido-minibuffer-setup)
- (add-hook 'choose-completion-string-functions 'ido-choose-completion-string))
- (define-minor-mode ido-everywhere
- "Toggle use of Ido for all buffer/file reading.
- With a prefix argument ARG, enable this feature if ARG is
- positive, and disable it otherwise. If called from Lisp,
- enable the mode if ARG is omitted or nil."
- :global t
- :group 'ido
- (remove-function read-file-name-function #'ido-read-file-name)
- (remove-function read-buffer-function #'ido-read-buffer)
- (when ido-everywhere
- (add-function :override read-file-name-function #'ido-read-file-name)
- (add-function :override read-buffer-function #'ido-read-buffer)))
- (defvar ido-minor-mode-map-entry nil)
- ;;;###autoload
- (defun ido-mode (&optional arg)
- "Toggle Ido mode on or off.
- With ARG, turn Ido mode on if arg is positive, off otherwise.
- Turning on Ido mode will remap (via a minor-mode keymap) the default
- keybindings for the `find-file' and `switch-to-buffer' families of
- commands to the Ido versions of these functions.
- However, if ARG arg equals `files', remap only commands for files, or
- if it equals `buffers', remap only commands for buffer switching.
- This function also adds a hook to the minibuffer."
- (interactive "P")
- (setq ido-mode
- (cond
- ((null arg) (if ido-mode nil 'both))
- ((eq arg t) 'both)
- ((eq arg 'files) 'file)
- ((eq arg 'buffers) 'buffer)
- ((memq arg '(file buffer both)) arg)
- ((> (prefix-numeric-value arg) 0) 'both)
- (t nil)))
- (ido-everywhere (if ido-everywhere 1 -1))
- (when ido-mode
- (ido-common-initialization)
- (ido-load-history)
- (add-hook 'kill-emacs-hook 'ido-kill-emacs-hook)
- (let ((map (make-sparse-keymap)))
- (when (memq ido-mode '(file both))
- (define-key map [remap find-file] 'ido-find-file)
- (define-key map [remap find-file-read-only] 'ido-find-file-read-only)
- (define-key map [remap find-alternate-file] 'ido-find-alternate-file)
- (define-key map [remap write-file] 'ido-write-file)
- (define-key map [remap insert-file] 'ido-insert-file)
- (define-key map [remap list-directory] 'ido-list-directory)
- (define-key map [remap dired] 'ido-dired)
- (define-key map [remap find-file-other-window]
- 'ido-find-file-other-window)
- (define-key map [remap find-file-read-only-other-window]
- 'ido-find-file-read-only-other-window)
- (define-key map [remap find-alternate-file-other-window]
- #'ido-find-alternate-file-other-window)
- (define-key map [remap dired-other-window] #'ido-dired-other-window)
- (define-key map [remap find-file-other-frame]
- 'ido-find-file-other-frame)
- (define-key map [remap find-file-read-only-other-frame]
- 'ido-find-file-read-only-other-frame)
- (define-key map [remap dired-other-frame] #'ido-dired-other-frame))
- (when (memq ido-mode '(buffer both))
- (define-key map [remap switch-to-buffer] 'ido-switch-buffer)
- (define-key map [remap switch-to-buffer-other-window]
- 'ido-switch-buffer-other-window)
- (define-key map [remap switch-to-buffer-other-frame]
- 'ido-switch-buffer-other-frame)
- (define-key map [remap insert-buffer] 'ido-insert-buffer)
- (define-key map [remap kill-buffer] 'ido-kill-buffer)
- (define-key map [remap display-buffer] 'ido-display-buffer)
- (define-key map [remap display-buffer-other-frame]
- #'ido-display-buffer-other-frame))
- (if ido-minor-mode-map-entry
- (setcdr ido-minor-mode-map-entry map)
- (setq ido-minor-mode-map-entry (cons 'ido-mode map))
- (add-to-list 'minor-mode-map-alist ido-minor-mode-map-entry))))
- (when (called-interactively-p 'any)
- (message "Ido mode %s" (if ido-mode "enabled" "disabled"))))
- ;;; IDO KEYMAP
- (defalias 'ido-init-completion-maps 'ignore "")
- (make-obsolete 'ido-init-completion-maps "it does nothing." "25.1")
- (defun ido-setup-completion-map ()
- "Set up the completion keymap used by Ido.
- Create a keymap, bind `ido-completion-map' to it, and depending
- on what is being completed (`ido-cur-item') set its parent keymap
- to one of:
- `ido-common-completion-map'
- `ido-file-dir-completion-map'
- `ido-file-completion-map'
- `ido-buffer-completion-map'
- If option `ido-context-switch-command' is non-nil or `viper-mode'
- is enabled then some keybindings are changed in the keymap."
- ;; generated every time so that it can inherit new functions.
- (let ((map (make-sparse-keymap))
- (viper-p (if (boundp 'viper-mode) viper-mode)))
- (when viper-p
- (define-key map [remap viper-intercept-ESC-key] 'ignore))
- (pcase ido-cur-item
- ((or `file `dir)
- (when ido-context-switch-command
- (define-key map "\C-x\C-b" ido-context-switch-command)
- (define-key map "\C-x\C-d" 'ignore))
- (when viper-p
- (define-key map [remap viper-backward-char]
- 'ido-delete-backward-updir)
- (define-key map [remap viper-del-backward-char-in-insert]
- 'ido-delete-backward-updir)
- (define-key map [remap viper-delete-backward-word]
- 'ido-delete-backward-word-updir))
- (set-keymap-parent map
- (if (eq ido-cur-item 'file)
- ido-file-completion-map
- ido-file-dir-completion-map)))
- (`buffer
- (when ido-context-switch-command
- (define-key map "\C-x\C-f" ido-context-switch-command))
- (set-keymap-parent map ido-buffer-completion-map))
- (_
- (set-keymap-parent map ido-common-completion-map)))
- (setq ido-completion-map map)))
- (defun ido-final-slash (dir &optional fix-it)
- ;; return DIR if DIR has final slash.
- ;; else if FIX-IT is non-nil, return DIR/
- ;; else return nil.
- (setq dir (ido-name dir))
- (cond
- ((string-match "/\\'" dir) dir)
- ((ido-is-tramp-root dir) dir)
- (fix-it (concat dir "/"))
- (t nil)))
- (defun ido-no-final-slash (s)
- ;; Remove optional final slash from string S
- (let ((l (1- (length s))))
- (if (and (> l 0) (eq (aref s l) ?/))
- (substring s 0 l)
- s)))
- (defun ido-nonreadable-directory-p (dir)
- ;; Return t if dir is a directory, but not readable
- ;; Do not check for non-readable directories via tramp, as this causes a premature
- ;; connect on incomplete tramp paths (after entering just method:).
- (let ((ido-enable-tramp-completion nil))
- (and (ido-final-slash dir)
- (not (ido-is-unc-host dir))
- (file-directory-p dir)
- (not (file-readable-p dir)))))
- (defun ido-directory-too-big-p (dir)
- ;; Return t if dir is a directory, but too big to show
- ;; Do not check for non-readable directories via tramp, as this causes a premature
- ;; connect on incomplete tramp paths (after entering just method:).
- (let ((ido-enable-tramp-completion nil))
- (and (numberp ido-max-directory-size)
- (ido-final-slash dir)
- (not (ido-is-unc-host dir))
- (file-directory-p dir)
- (> (nth 7 (file-attributes (file-truename dir))) ido-max-directory-size))))
- (defun ido-set-current-directory (dir &optional subdir no-merge)
- ;; Set ido's current directory to DIR or DIR/SUBDIR
- (unless (and ido-enable-tramp-completion
- (string-match "\\`/[^/]*@\\'" dir))
- (setq dir (ido-final-slash dir t)))
- (setq ido-use-merged-list nil
- ido-try-merged-list (not no-merge))
- (when subdir
- (setq dir (concat dir subdir))
- (unless (and ido-enable-tramp-completion
- (string-match "\\`/[^/]*@\\'" dir))
- (setq dir (ido-final-slash dir t))))
- (and ido-completion-buffer
- (get-buffer ido-completion-buffer)
- (kill-buffer ido-completion-buffer))
- (cond
- ((equal dir ido-current-directory)
- nil)
- ((ido-is-unc-root dir)
- (ido-trace "unc" dir)
- (setq ido-current-directory dir)
- (setq ido-directory-nonreadable nil)
- (setq ido-directory-too-big nil)
- t)
- (t
- (ido-trace "cd" dir)
- (setq ido-current-directory dir)
- (and ido-completion-buffer
- (get-buffer ido-completion-buffer)
- (kill-buffer ido-completion-buffer))
- (setq ido-directory-nonreadable (ido-nonreadable-directory-p dir))
- (setq ido-directory-too-big (and (not ido-directory-nonreadable)
- (ido-directory-too-big-p dir)))
- t)))
- (defun ido-set-current-home (&optional dir)
- ;; Set ido's current directory to user's home directory
- (ido-set-current-directory (expand-file-name (or dir "~/"))))
- (defun ido-record-command (command arg)
- "Add (COMMAND ARG) to `command-history' if `ido-record-commands' is non-nil."
- (if ido-record-commands ; FIXME: use `when' instead of `if'?
- (let ((cmd (list command arg)))
- (if (or (not command-history) ; FIXME: ditto
- (not (equal cmd (car command-history))))
- (setq command-history (cons cmd command-history))))))
- (defun ido-make-prompt (item prompt)
- ;; Make the prompt for ido-read-internal
- (cond
- ((and (memq item '(file dir)) ido-current-directory)
- (let ((dirname (abbreviate-file-name ido-current-directory))
- (max-width (if (and ido-max-file-prompt-width (floatp ido-max-file-prompt-width))
- (floor (* (frame-width) ido-max-file-prompt-width))
- ido-max-file-prompt-width))
- (literal (and (boundp 'ido-find-literal) ido-find-literal "(literal) "))
- (vc-off (and ido-saved-vc-hb (not vc-handled-backends) "[-VC] "))
- (prefix nil)
- (rule ido-rewrite-file-prompt-rules))
- (let ((case-fold-search nil))
- (while rule
- (if (and (consp (car rule))
- (string-match (car (car rule)) dirname))
- (setq dirname
- (if (stringp (cdr (car rule)))
- (replace-match (cdr (car rule)) t nil dirname)
- (funcall (cdr (car rule)) dirname))))
- (setq rule (cdr rule))))
- (run-hooks 'ido-rewrite-file-prompt-functions)
- (concat prompt
- ; (if ido-process-ignore-lists "" "&")
- (or literal "")
- (or vc-off "")
- (or prefix "")
- (let ((l (length dirname)))
- (if (and max-width (> max-width 0) (> l max-width))
- (let* ((s (substring dirname (- max-width)))
- (i (string-match "/" s)))
- (concat "..." (if i (substring s i) s)))
- dirname)))))
- (t prompt)))
- ;; Here is very briefly how ido-find-file works:
- ;;
- ;; (ido-find-file)
- ;; (ido-file-internal method)
- ;; set ido-current-directory
- ;; (ido-read-internal 'file ...)
- ;; (while ...
- ;; (ido-make-item-list ...)
- ;; (ido-set-matches)
- ;; (completing-read ... ido-text-init ...)
- ;;
- ;; ... here user is allowed to type characters and commands
- ;; a command may set ido-exit and call (exit-minibuffer)
- ;; to make ido-read-internal do advanced tasks (or return)
- ;;
- ;; ... ido-tidy and ido-exhibit are pre- and post-hooks
- ;; which are run before and after each user command.
- ;;
- ;; return value from completing-read is stored in ido-final-text
- ;; - ido-exit may cause further actions to be taken:
- ;; 'refresh - repeat loop (make-item-list, set-matches)
- ;; 'edit - edit the prompt string, then repeat loop
- ;; 'keep - repeat loop but don't (re)make-item-list
- ;; 'updir - go up one directory, repeat loop
- ;; else set ido-selected based on ido-final-text,
- ;; optionally update ido-current-directory and repeat loop, or
- ;; exit with the return value of ido-selected (file name)
- ;; selected file name is returned from ido-read-internal,
- ;; ido-exit and method determines what action is taken
- ;; e.g. the file name may be ignored or joined with ido-current-directory, and
- ;; the relevant function is called (find-file, write-file, etc).
- (defun ido-read-internal (item prompt hist &optional default require-match initial)
- "Perform the `ido-read-buffer' and `ido-read-file-name' functions.
- Return the name of a buffer or file selected.
- PROMPT is the prompt to give to the user.
- DEFAULT if given is the default item to start with.
- If REQUIRE-MATCH is non-nil, an existing file must be selected.
- If INITIAL is non-nil, it specifies the initial input string."
- (let
- ((ido-cur-item item)
- (ido-entry-buffer (current-buffer))
- (ido-process-ignore-lists t)
- (ido-process-ignore-lists-inhibit nil)
- (ido-set-default-item t)
- ido-default-item
- ido-selected
- ido-final-text
- (done nil)
- (icomplete-mode nil) ;; prevent icomplete starting up
- ;; Exported dynamic variables:
- ido-cur-list
- ido-ignored-list
- (ido-rotate-temp nil)
- (ido-keep-item-list nil)
- (ido-use-merged-list nil)
- (ido-try-merged-list t)
- (ido-pre-merge-state nil)
- (ido-case-fold ido-case-fold)
- (ido-enable-prefix ido-enable-prefix)
- (ido-enable-regexp ido-enable-regexp)
- (ido-show-confirm-message nil)
- )
- (ido-setup-completion-map)
- (setq ido-text-init initial)
- (setq ido-input-stack nil)
- (run-hooks 'ido-setup-hook)
- (while (not done)
- (ido-trace "\n_LOOP_" ido-text-init)
- (setq ido-exit nil)
- (setq ido-rescan t)
- (setq ido-rotate nil)
- (setq ido-text "")
- (when ido-set-default-item
- (setq ido-default-item
- (cond
- ((eq item 'buffer)
- (if (bufferp default) (buffer-name default) default))
- ((stringp default)
- (if (memq item '(file dir))
- (file-name-nondirectory default)
- default))
- ((eq item 'file)
- (and ido-enable-last-directory-history
- (let ((d (assoc ido-current-directory ido-last-directory-list)))
- (and d (cdr d)))))))
- (if (member ido-default-item ido-ignore-item-temp-list)
- (setq ido-default-item nil))
- (ido-trace "new default" ido-default-item)
- (if ido-default-item
- (setq ido-initial-position 0))
- (setq ido-set-default-item nil))
- (if ido-process-ignore-lists-inhibit
- (setq ido-process-ignore-lists nil))
- (if (and ido-use-merged-list (memq ido-try-merged-list '(t wide)) (not ido-keep-item-list))
- (let ((olist ido-cur-list)
- (oign ido-ignored-list)
- (omat ido-matches)
- (l (ido-make-merged-file-list ido-text-init
- (eq ido-use-merged-list 'auto)
- (eq ido-try-merged-list 'wide))))
- (ido-trace "merged" l)
- (cond
- ((not l)
- (if (eq ido-try-merged-list 'wide)
- (setq ido-pre-merge-state
- (list "" ido-current-directory olist oign omat)
- ido-cur-list nil
- ido-ignored-list nil
- ido-matches nil
- ido-keep-item-list t
- ido-try-merged-list (if (eq ido-use-merged-list 'auto) 'auto nil)
- ido-use-merged-list nil)
- (setq ido-cur-list olist
- ido-ignored-list oign
- ido-matches omat
- ido-keep-item-list t
- ido-try-merged-list (if (eq ido-use-merged-list 'auto) 'auto nil)
- ido-use-merged-list nil)))
- ((eq l t)
- (setq ido-use-merged-list nil))
- ((eq l 'input-pending-p)
- (setq ido-try-merged-list t
- ido-use-merged-list nil))
- (t
- (setq ido-pre-merge-state
- (list ido-text-init ido-current-directory olist oign omat))
- (ido-set-current-directory (car (cdr (car l))))
- (if (ido-final-slash ido-text-init)
- (setq ido-text-init ""))
- (setq ido-cur-list l
- ido-ignored-list nil
- ido-matches l
- ido-rescan nil
- ido-keep-item-list t
- ido-use-merged-list t)
- (ido-trace "Merged" t)
- ))))
- (cond
- (ido-keep-item-list
- (setq ido-keep-item-list nil
- ido-rescan nil))
- ((eq ido-cur-item 'file)
- (setq ido-ignored-list nil
- ido-cur-list (and (not ido-directory-nonreadable)
- (not ido-directory-too-big)
- (ido-make-file-list ido-default-item))))
- ((eq ido-cur-item 'dir)
- (setq ido-ignored-list nil
- ido-cur-list (and (not ido-directory-nonreadable)
- (not ido-directory-too-big)
- (ido-make-dir-list ido-default-item))))
- ((eq ido-cur-item 'buffer)
- (setq ido-ignored-list nil
- ido-cur-list (ido-make-buffer-list ido-default-item)))
- ((eq ido-cur-item 'list)
- (setq ido-ignored-list nil
- ido-cur-list (ido-make-choice-list ido-default-item)))
- (t nil))
- (setq ido-rotate-temp nil)
- (if ido-process-ignore-lists-inhibit
- (setq ido-process-ignore-lists t
- ido-process-ignore-lists-inhibit nil))
- (ido-set-matches)
- (if (and ido-matches (eq ido-try-merged-list 'auto))
- (setq ido-try-merged-list t))
- (let ((max-mini-window-height (or ido-max-window-height
- (and (boundp 'max-mini-window-height)
- max-mini-window-height)))
- (ido-completing-read t)
- (ido-require-match require-match)
- (ido-use-mycompletion-depth (1+ (minibuffer-depth)))
- (show-paren-mode nil)
- ;; Postpone history adding till later
- (history-add-new-input nil))
- ;; prompt the user for the file name
- (setq ido-exit nil)
- (setq ido-final-text
- (catch 'ido
- (read-from-minibuffer (ido-make-prompt item prompt)
- (prog1 ido-text-init
- (setq ido-text-init nil))
- ido-completion-map nil hist))))
- (ido-trace "read-from-minibuffer" ido-final-text)
- (and ido-completion-buffer
- (get-buffer ido-completion-buffer)
- (kill-buffer ido-completion-buffer))
- (ido-trace "\n_EXIT_" ido-exit)
- (cond
- ((eq ido-exit 'refresh)
- (if (and (eq ido-use-merged-list 'auto)
- (or (input-pending-p)))
- (setq ido-use-merged-list nil
- ido-keep-item-list t))
- nil)
- ((eq ido-exit 'done)
- (setq done t
- ido-selected ido-text
- ido-exit nil))
- ((memq ido-exit '(edit chdir))
- (cond
- ((memq ido-cur-item '(file dir))
- (let* ((read-file-name-function nil)
- (edit (eq ido-exit 'edit))
- (d ido-current-directory)
- (f ido-text-init)
- (new t))
- (setq ido-text-init "")
- (while new
- (setq new (if edit
- (condition-case nil
- (read-file-name (concat prompt "[EDIT] ")
- (expand-file-name d)
- (concat d f) nil f)
- (quit (concat d f)))
- f)
- d (or (file-name-directory new) "/")
- f (file-name-nondirectory new)
- edit t)
- (if (or
- (file-directory-p d)
- (and (yes-or-no-p (format "Create directory %s? " d))
- (condition-case nil
- (progn (make-directory d t) t)
- (error
- (message "Could not create directory")
- (sit-for 1)
- nil))))
- (progn
- (ido-set-current-directory d nil (eq ido-exit 'chdir))
- (setq ido-text-init f
- new nil))))))
- (t
- (setq ido-text-init
- (condition-case nil
- (read-string (concat prompt "[EDIT] ") ido-final-text)
- (quit ido-final-text)))))
- nil)
- ((eq ido-exit 'keep)
- (setq ido-keep-item-list t))
- ((memq ido-exit '(dired fallback find-file switch-to-buffer insert-buffer insert-file))
- (setq done t))
- ((memq ido-exit '(updir push))
- ;; cannot go up if already at the root-dir (Unix) or at the
- ;; root-dir of a certain drive (Windows or MS-DOS).
- (if (ido-is-tramp-root)
- (when (string-match "\\`\\(/\\([^/]+[:@]\\)*\\)\\([^/]+\\)[:@]\\'" ido-current-directory)
- (setq ido-text-init (match-string 3 ido-current-directory))
- (ido-set-current-directory (match-string 1 ido-current-directory))
- (setq ido-set-default-item t))
- (unless (ido-is-root-directory)
- (when (eq ido-exit 'push)
- (setq ido-input-stack (cons (cons ido-cur-item ido-text) ido-input-stack))
- (setq ido-cur-item 'dir)
- (setq ido-text-init (file-name-nondirectory (substring ido-current-directory 0 -1)))
- (ido-trace "push" ido-input-stack))
- (ido-set-current-directory (file-name-directory (substring ido-current-directory 0 -1)))
- (setq ido-set-default-item t))))
- ((eq ido-exit 'pop)
- (ido-trace "pop" ido-input-stack)
- (let ((elt (car ido-input-stack)))
- (setq ido-input-stack (cdr ido-input-stack))
- (ido-set-current-directory (concat ido-current-directory ido-text))
- (setq ido-cur-item (car elt))
- (setq ido-text-init (cdr elt))))
- ((eq ido-exit 'pop-all)
- (ido-trace "pop-all" ido-input-stack)
- (while ido-input-stack
- (let ((elt (car ido-input-stack)))
- (setq ido-input-stack (cdr ido-input-stack))
- (ido-set-current-directory (concat ido-current-directory ido-text))
- (setq ido-cur-item (car elt))
- (setq ido-text-init (cdr elt)))))
- ;; Handling the require-match must be done in a better way.
- ((and require-match
- (not (memq require-match '(confirm confirm-after-completion)))
- (not (if ido-directory-too-big
- (file-exists-p (concat ido-current-directory ido-final-text))
- (ido-existing-item-p))))
- (error "Must specify valid item"))
- (t
- (setq ido-selected
- (if (or (eq ido-exit 'takeprompt)
- (null ido-matches))
- ido-final-text
- ;; else take head of list
- (ido-name (car ido-matches))))
- (cond
- ((memq item '(buffer list))
- (setq done t))
- ((string-equal "./" ido-selected)
- nil)
- ((string-equal "../" ido-selected)
- ;; cannot go up if already at the root-dir (Unix) or at the
- ;; root-dir of a certain drive (Windows or MS-DOS).
- (or (ido-is-root-directory)
- (ido-set-current-directory (file-name-directory (substring ido-current-directory 0 -1))))
- (setq ido-set-default-item t))
- ((and (string-match (if ido-enable-tramp-completion ".[:@]\\'" ".:\\'") ido-selected)
- (ido-is-root-directory) ;; Ange-ftp or Tramp
- (not (ido-local-file-exists-p ido-selected)))
- (ido-set-current-directory ido-current-directory ido-selected)
- (ido-trace "tramp prefix" ido-selected)
- (if (ido-is-slow-ftp-host)
- (setq ido-exit 'fallback
- done t)
- (setq ido-set-default-item t)))
- ((string-match (if (memq system-type '(windows-nt ms-dos))
- "\\`[a-zA-Z]:\\|[/\\][^/\\]"
- "/[^/]")
- ido-selected)
- (ido-set-current-directory (file-name-directory ido-selected))
- (setq ido-set-default-item t))
- ((string-match "\\`~" ido-selected)
- (ido-set-current-home ido-selected))
- ((ido-final-slash ido-selected)
- (if ido-enable-last-directory-history
- (let ((x (assoc ido-current-directory ido-last-directory-list)))
- (if x
- (setcdr x ido-selected)
- (setq ido-last-directory-list
- (cons (cons ido-current-directory ido-selected) ido-last-directory-list)))))
- (ido-set-current-directory ido-current-directory ido-selected)
- (if ido-input-stack
- ; automatically pop stack elements which match existing files or directories
- (let (elt)
- (while (and (setq elt (car ido-input-stack))
- (file-exists-p (concat ido-current-directory (cdr elt))))
- (if (setq ido-input-stack (cdr ido-input-stack))
- (ido-set-current-directory ido-current-directory (cdr elt))
- (setq ido-text-init (cdr elt)))
- (setq ido-cur-item (car elt))))
- (setq ido-set-default-item t)))
- (t
- (setq done t))))))
- (add-to-history (cond
- ((consp hist)
- (or (car hist) 'minibuffer-history))
- (hist hist)
- (t 'minibuffer-history))
- ido-selected)
- ido-selected))
- (defun ido-edit-input ()
- "Edit absolute file name entered so far with Ido; terminate by RET.
- If cursor is not at the end of the user input, move to end of input."
- (interactive)
- (if (not (eobp))
- (end-of-line)
- (setq ido-text-init (if ido-matches (ido-name (car ido-matches)) ido-text))
- (setq ido-exit 'edit)
- (exit-minibuffer)))
- ;;; MAIN FUNCTIONS
- (defun ido-buffer-internal (method &optional fallback prompt default initial switch-cmd)
- ;; Internal function for ido-switch-buffer and friends
- (if (not ido-mode)
- (progn
- (run-hook-with-args 'ido-before-fallback-functions
- (or fallback 'switch-to-buffer))
- (call-interactively (or fallback 'switch-to-buffer)))
- (let* ((ido-context-switch-command switch-cmd)
- (ido-current-directory nil)
- (ido-directory-nonreadable nil)
- (ido-directory-too-big nil)
- (ido-enable-virtual-buffers (and ido-use-virtual-buffers
- (not (eq ido-use-virtual-buffers 'auto))))
- (require-match (confirm-nonexistent-file-or-buffer))
- (buf (ido-read-internal 'buffer (or prompt "Buffer: ") 'ido-buffer-history default
- require-match initial))
- filename)
- ;; Choose the buffer name: either the text typed in, or the head
- ;; of the list of matches
- (cond
- ((eq ido-exit 'find-file)
- (ido-file-internal
- (if (memq method '(other-window other-frame)) method ido-default-file-method)
- nil nil nil nil ido-text))
- ((eq ido-exit 'insert-file)
- (ido-file-internal 'insert 'insert-file nil "Insert file: " nil ido-text 'ido-enter-insert-buffer))
- ((eq ido-exit 'fallback)
- (let ((read-buffer-function nil))
- (setq this-command (or fallback 'switch-to-buffer))
- (run-hook-with-args 'ido-before-fallback-functions this-command)
- (call-interactively this-command)))
- ;; Check buf is non-nil.
- ((not buf) nil)
- ((= (length buf) 0) nil)
- ;; View buffer if it exists
- ((get-buffer buf)
- (add-to-history 'buffer-name-history buf)
- (if (eq method 'insert)
- (progn
- (ido-record-command 'insert-buffer buf)
- (push-mark
- (save-excursion
- (insert-buffer-substring (get-buffer buf))
- (point))))
- (ido-visit-buffer buf method t)))
- ;; check for a virtual buffer reference
- ((and ido-enable-virtual-buffers
- ido-virtual-buffers
- (setq filename (assoc buf ido-virtual-buffers)))
- (ido-visit-buffer (find-file-noselect (cdr filename)) method t))
- ((and (eq ido-create-new-buffer 'prompt)
- (null require-match)
- (not (y-or-n-p (format-message
- "No buffer matching `%s', create one? " buf))))
- nil)
- ;; buffer doesn't exist
- ((and (eq ido-create-new-buffer 'never)
- (null require-match))
- (message "No buffer matching `%s'" buf))
- ((and (eq ido-create-new-buffer 'prompt)
- (null require-match)
- (not (y-or-n-p (format-message
- "No buffer matching `%s', create one? " buf))))
- nil)
- ;; create a new buffer
- (t
- (add-to-history 'buffer-name-history buf)
- (setq buf (get-buffer-create buf))
- (if (fboundp 'set-buffer-major-mode)
- (set-buffer-major-mode buf))
- (ido-visit-buffer buf method t))))))
- (defun ido-record-work-directory (&optional dir)
- (when (and (numberp ido-max-work-directory-list) (> ido-max-work-directory-list 0))
- (if (and (setq dir (or dir ido-current-directory)) (> (length dir) 0))
- (let ((items ido-work-directory-list-ignore-regexps)
- (case-fold-search nil))
- (while (and items dir)
- (if (string-match (car items) dir)
- (setq dir nil))
- (setq items (cdr items)))
- (if dir
- (setq ido-work-directory-list (cons dir (delete dir ido-work-directory-list))))))
- (if (> (length ido-work-directory-list) ido-max-work-directory-list)
- (setcdr (nthcdr (1- ido-max-work-directory-list) ido-work-directory-list) nil))))
- (defun ido-forget-work-directory ()
- (interactive)
- (when (and ido-current-directory ido-work-directory-list)
- (setq ido-work-directory-list (delete ido-current-directory ido-work-directory-list))
- (when ido-use-merged-list
- (ido-undo-merge-work-directory)
- (setq ido-exit 'refresh
- ido-try-merged-list t
- ido-use-merged-list t
- ido-text-init ido-text
- ido-rotate-temp t)
- (exit-minibuffer))))
- (defun ido-record-work-file (name)
- ;; Save NAME in ido-work-file-list
- (when (and (numberp ido-max-work-file-list) (> ido-max-work-file-list 0))
- (or
- (and ido-work-file-list (equal (car ido-work-file-list) name))
- (setq ido-work-file-list (cons name (delete name ido-work-file-list))))
- (if (> (length ido-work-file-list) ido-max-work-file-list)
- (setcdr (nthcdr (1- ido-max-work-file-list) ido-work-file-list) nil))))
- (defun ido-expand-directory (dir)
- ;; Expand DIR or use DEFAULT-DIRECTORY if nil.
- ;; Add final slash to result in case it was missing from DEFAULT-DIRECTORY.
- (ido-final-slash (expand-file-name (or dir default-directory)) t))
- (defun ido-file-internal (method &optional fallback default prompt item initial switch-cmd)
- ;; Internal function for ido-find-file and friends
- (unless item
- (setq item 'file))
- (let ((ido-current-directory (ido-expand-directory default))
- (ido-context-switch-command switch-cmd)
- ido-directory-nonreadable ido-directory-too-big
- filename)
- (if (or (not ido-mode) (ido-is-slow-ftp-host))
- (setq filename t
- ido-exit 'fallback)
- (setq ido-directory-nonreadable
- (ido-nonreadable-directory-p ido-current-directory)
- ido-directory-too-big
- (and (not ido-directory-nonreadable)
- (ido-directory-too-big-p ido-current-directory))))
- (when (and (eq item 'file)
- (or ido-use-url-at-point ido-use-filename-at-point))
- (let (fn)
- (require 'ffap)
- ;; Duplicate code from ffap-guesser as we want different
- ;; behavior for files and URLs.
- (cond
- ((with-no-warnings
- (and ido-use-url-at-point
- ffap-url-regexp
- (ffap-fixup-url (or (ffap-url-at-point)
- (ffap-gopher-at-point)))))
- (setq ido-exit 'ffap
- filename t))
- ((and ido-use-filename-at-point
- (setq fn (with-no-warnings
- (if (eq ido-use-filename-at-point 'guess)
- (ffap-guesser)
- (ffap-string-at-point))))
- (not (string-match "\\`http:/" fn)))
- (let ((absolute-fn (expand-file-name fn)))
- (cond
- ((file-directory-p absolute-fn)
- (setq ido-current-directory
- (file-name-as-directory absolute-fn)))
- ((file-directory-p (file-name-directory absolute-fn))
- (setq ido-current-directory (file-name-directory absolute-fn))
- (setq initial (file-name-nondirectory absolute-fn)))))))))
- (let (ido-saved-vc-hb
- (vc-handled-backends (and (boundp 'vc-handled-backends)
- vc-handled-backends))
- (ido-work-directory-index -1)
- (ido-work-file-index -1)
- (ido-find-literal nil))
- (unless filename
- (setq ido-saved-vc-hb vc-handled-backends)
- (let ((minibuffer-completing-file-name t))
- (setq filename
- (ido-read-internal item
- (or prompt "Find file: ")
- 'ido-file-history
- (and (eq method 'alt-file) buffer-file-name)
- (confirm-nonexistent-file-or-buffer)
- initial))))
- ;; Choose the file name: either the text typed in, or the head
- ;; of the list of matches
- (cond
- ((eq ido-exit 'fallback)
- ;; Need to guard setting of default-directory here, since
- ;; we don't want to change directory of current buffer.
- (let ((default-directory ido-current-directory)
- (read-file-name-function nil))
- (setq this-command (or fallback 'find-file))
- (run-hook-with-args 'ido-before-fallback-functions this-command)
- (call-interactively this-command)))
- ((eq ido-exit 'switch-to-buffer)
- (ido-buffer-internal
- (if (memq method '(other-window other-frame))
- method ido-default-buffer-method)
- nil nil nil ido-text))
- ((eq ido-exit 'insert-buffer)
- (ido-buffer-internal 'insert 'insert-buffer "Insert buffer: "
- nil ido-text 'ido-enter-insert-file))
- ((eq ido-exit 'dired)
- (funcall (cond ((eq method 'other-window) 'dired-other-window)
- ((eq method 'other-frame) 'dired-other-frame)
- (t 'dired))
- (concat ido-current-directory (or ido-text ""))))
- ((eq ido-exit 'ffap)
- (find-file-at-point))
- ((eq method 'alt-file)
- (ido-record-work-file filename)
- (setq default-directory ido-current-directory)
- (ido-record-work-directory)
- (find-alternate-file filename))
- ((eq method 'alt-file-other-window)
- (ido-record-work-file filename)
- (setq default-directory ido-current-directory)
- (ido-record-work-directory)
- (find-alternate-file-other-window filename))
- ((memq method '(dired dired-other-window dired-other-frame
- list-directory))
- (if (equal filename ".")
- (setq filename ""))
- (let* ((dirname (ido-final-slash
- (concat ido-current-directory filename) t))
- (file (substring dirname 0 -1)))
- (cond
- ((file-directory-p dirname)
- (ido-record-command method dirname)
- (ido-record-work-directory dirname)
- (funcall method dirname))
- ((file-directory-p ido-current-directory)
- (cond
- ((file-exists-p file)
- (ido-record-command method ido-current-directory)
- (ido-record-work-directory)
- (funcall method ido-current-directory)
- (if (eq method 'dired)
- (with-no-warnings
- (dired-goto-file (expand-file-name file)))))
- ((string-match "[[*?]" filename)
- (setq dirname (concat ido-current-directory filename))
- (ido-record-command method dirname)
- (ido-record-work-directory)
- (funcall method dirname))
- ((y-or-n-p (format "Directory %s does not exist. Create it? "
- filename))
- (ido-record-command method dirname)
- (ido-record-work-directory dirname)
- (make-directory-internal dirname)
- (funcall method dirname))
- (t
- ;; put make-directory command on history
- (ido-record-command 'make-directory dirname))))
- (t (error "No such directory")))))
- ((eq method 'write)
- (ido-record-work-file filename)
- (setq default-directory ido-current-directory)
- (setq filename (concat ido-current-directory filename))
- (ido-record-command 'write-file filename)
- (add-to-history 'file-name-history filename)
- (ido-record-work-directory)
- (write-file filename t))
- ((eq method 'read-only)
- (ido-record-work-file filename)
- (setq filename (concat ido-current-directory filename))
- (ido-record-command fallback filename)
- (ido-record-work-directory)
- (run-hook-with-args 'ido-before-fallback-functions fallback)
- (funcall fallback filename))
- ((eq method 'insert)
- (ido-record-work-file filename)
- (setq filename (concat ido-current-directory filename))
- (ido-record-command
- (if ido-find-literal 'insert-file-literally 'insert-file)
- filename)
- (add-to-history 'file-name-history filename)
- (ido-record-work-directory)
- (insert-file-1 filename
- (if ido-find-literal
- #'insert-file-contents-literally
- #'insert-file-contents)))
- (filename
- (ido-record-work-file filename)
- (setq filename (concat ido-current-directory filename))
- (ido-record-command 'find-file filename)
- (add-to-history 'file-name-history filename)
- (ido-record-work-directory)
- (ido-visit-buffer (find-file-noselect filename nil ido-find-literal)
- method))))))
- (defun ido-existing-item-p ()
- ;; Return non-nil if there is a matching item
- (not (null ido-matches)))
- ;;; COMPLETION CODE
- (defun ido-set-common-completion ()
- ;; Find common completion of `ido-text' in `ido-matches'
- ;; The result is stored in `ido-common-match-string'
- (let (val)
- (setq ido-common-match-string nil)
- (if (and ido-matches
- (not ido-enable-regexp) ;; testing
- (stringp ido-text)
- (> (length ido-text) 0))
- (if (setq val (ido-find-common-substring ido-matches ido-text))
- (setq ido-common-match-string val)))
- val))
- (defun ido-complete ()
- "Try and complete the current pattern amongst the file names."
- (interactive)
- (let (res)
- (cond
- (ido-incomplete-regexp
- ;; Do nothing
- )
- ((and (memq ido-cur-item '(file dir))
- (string-match "[$]" ido-text))
- (let ((evar (substitute-in-file-name (concat ido-current-directory ido-text))))
- (if (not (file-exists-p (file-name-directory evar)))
- (message "Expansion generates non-existing directory name")
- (if (file-directory-p evar)
- (ido-set-current-directory evar)
- (let ((d (or (file-name-directory evar) "/"))
- (f (file-name-nondirectory evar)))
- (when (file-directory-p d)
- (ido-set-current-directory d)
- (setq ido-text-init f))))
- (setq ido-exit 'refresh)
- (exit-minibuffer))))
- (ido-directory-too-big
- (setq ido-directory-too-big nil)
- (setq ido-text-init ido-text)
- (setq ido-exit 'refresh)
- (exit-minibuffer))
- ((not ido-matches)
- (when ido-completion-buffer
- (call-interactively (setq this-command ido-cannot-complete-command))))
- ((and (= 1 (length ido-matches))
- (not (and ido-enable-tramp-completion
- (string-equal ido-current-directory "/")
- (string-match ".[@:]\\'" (ido-name (car ido-matches)))))
- (not (ido-local-file-exists-p (ido-name (car ido-matches)))))
- ;; only one choice, so select it.
- (if (not ido-confirm-unique-completion)
- (exit-minibuffer)
- (setq ido-rescan (not ido-enable-prefix))
- (delete-region (minibuffer-prompt-end) (point))
- (insert (ido-name (car ido-matches)))))
- (t ;; else there could be some completions
- (setq res ido-common-match-string)
- (if (and (not (memq res '(t nil)))
- (not (equal res ido-text)))
- ;; found something to complete, so put it in the minibuffer.
- (progn
- ;; move exact match to front if not in prefix mode
- (setq ido-rescan (not ido-enable-prefix))
- (delete-region (minibuffer-prompt-end) (point))
- (insert res))
- ;; else nothing to complete
- (call-interactively (setq this-command ido-cannot-complete-command))
- )))))
- (defun ido-complete-space ()
- "Try completion unless inserting the space makes sense."
- (interactive)
- (if (and (stringp ido-common-match-string)
- (stringp ido-text)
- (cond
- ((> (length ido-common-match-string) (length ido-text))
- (= (aref ido-common-match-string (length ido-text)) ? ))
- (ido-matches
- (let (insert-space
- (re (concat (regexp-quote ido-text) " "))
- (comp ido-matches))
- (while comp
- (if (string-match re (ido-name (car comp)))
- (setq comp nil insert-space t)
- (setq comp (cdr comp))))
- insert-space))
- (t nil)))
- (insert " ")
- (ido-complete)))
- (defun ido-undo-merge-work-directory (&optional text try refresh)
- "Undo or redo last Ido directory merge operation.
- If no merge has yet taken place, toggle automatic merging option."
- (interactive)
- (cond
- (ido-pre-merge-state
- (ido-set-current-directory (nth 1 ido-pre-merge-state))
- (setq ido-text-init (or text (car ido-pre-merge-state))
- ido-cur-list (nth 2 ido-pre-merge-state)
- ido-ignored-list (nth 3 ido-pre-merge-state)
- ido-matches (nth 4 ido-pre-merge-state)
- ido-use-merged-list nil
- ido-try-merged-list try
- ido-keep-item-list (not refresh)
- ido-rescan nil
- ido-exit 'refresh
- ido-pre-merge-state nil)
- (exit-minibuffer))
- (text
- nil)
- (ido-try-merged-list
- (setq ido-try-merged-list nil))
- (ido-matches
- (setq ido-try-merged-list t))
- ((not ido-use-merged-list)
- (ido-merge-work-directories))))
- ;;; Magic C-f
- (defun ido-magic-forward-char (arg)
- "Move forward in user input or perform magic action.
- If no user input is present, or at end of input, perform magic actions:
- C-x C-b ... C-f switch to `ido-find-file'.
- C-x C-f ... C-f fallback to non-Ido `find-file'.
- C-x C-d ... C-f fallback to non-Ido brief `dired'.
- C-x d ... C-f fallback to non-Ido `dired'."
- (interactive "P")
- (cond
- ((or arg (not (eobp)))
- (forward-char (min (prefix-numeric-value arg)
- (- (point-max) (point)))))
- ((memq ido-cur-item '(file dir))
- (ido-fallback-command))
- (ido-context-switch-command
- (call-interactively ido-context-switch-command))
- ((eq ido-cur-item 'buffer)
- (ido-enter-find-file))))
- ;;; Magic C-b
- (defun ido-magic-backward-char (arg)
- "Move backward in user input or perform magic action.
- If no user input is present, or at start of input, perform magic actions:
- C-x C-f C-b switch to `ido-switch-buffer'.
- C-x C-d C-b switch to `ido-switch-buffer'.
- C-x d C-b switch to `ido-switch-buffer'.
- C-x C-b C-b fallback to non-Ido `switch-to-buffer'."
- (interactive "P")
- (cond
- ((or arg (> (point) (minibuffer-prompt-end)))
- (forward-char
- (- (min (prefix-numeric-value arg)
- (- (point) (minibuffer-prompt-end))))))
- ((eq last-command this-command)
- (when (and (memq ido-cur-item '(file dir))
- (not (bobp)))
- (ido-push-dir))) ; else do nothing
- ((eq ido-cur-item 'buffer)
- (ido-fallback-command))
- (ido-context-switch-command
- (call-interactively ido-context-switch-command))
- (t
- (ido-enter-switch-buffer))))
- ;;; Magic C-d
- (defun ido-magic-delete-char (arg)
- "Delete following char in user input or perform magic action.
- If at end of user input, perform magic actions:
- C-x C-f ... C-d enter `dired' on current directory."
- (interactive "P")
- (cond
- ((or arg (not (eobp)))
- (delete-char (min (prefix-numeric-value arg)
- (- (point-max) (point)))))
- (ido-context-switch-command
- nil)
- ((memq ido-cur-item '(file dir))
- (ido-enter-dired))))
- ;;; TOGGLE FUNCTIONS
- (defun ido-toggle-case ()
- "Toggle the value of `ido-case-fold'."
- (interactive)
- (setq ido-case-fold (not ido-case-fold))
- ;; ask for list to be regenerated.
- (setq ido-rescan t))
- (defun ido-toggle-regexp ()
- "Toggle the value of `ido-enable-regexp'."
- (interactive)
- (setq ido-enable-regexp (not ido-enable-regexp))
- ;; ask for list to be regenerated.
- (setq ido-rescan t))
- (defun ido-toggle-prefix ()
- "Toggle the value of `ido-enable-prefix'."
- (interactive)
- (setq ido-enable-prefix (not ido-enable-prefix))
- ;; ask for list to be regenerated.
- (setq ido-rescan t))
- (defun ido-toggle-ignore ()
- "Toggle ignoring files specified with `ido-ignore-files'."
- (interactive)
- (if (and (not (eobp)) (> (point) (minibuffer-prompt-end)))
- (goto-char (minibuffer-prompt-end))
- (if ido-directory-too-big
- (progn
- (message "Reading directory...")
- (setq ido-directory-too-big nil))
- (setq ido-process-ignore-lists (not ido-process-ignore-lists)))
- (setq ido-text-init ido-text)
- (setq ido-exit 'refresh)
- (exit-minibuffer)))
- (defun ido-toggle-vc ()
- "Toggle version control for this file."
- (interactive)
- (if (and ido-mode (eq ido-cur-item 'file))
- (progn
- (setq vc-handled-backends
- (if vc-handled-backends nil ido-saved-vc-hb))
- (setq ido-text-init ido-text)
- (setq ido-exit 'keep)
- (exit-minibuffer))))
- (defun ido-toggle-literal ()
- "Toggle literal reading of this file."
- (interactive)
- (if (and ido-mode (eq ido-cur-item 'file))
- (progn
- (setq ido-find-literal (not ido-find-literal))
- (setq ido-text-init ido-text)
- (setq ido-exit 'keep)
- (exit-minibuffer))))
- (defun ido-toggle-virtual-buffers ()
- "Toggle the use of virtual buffers.
- See `ido-use-virtual-buffers' for explanation of virtual buffer."
- (interactive)
- (when (and ido-mode (eq ido-cur-item 'buffer))
- (setq ido-enable-virtual-buffers
- (if ido-enable-virtual-buffers
- nil
- ;; Use `always' instead of t for `ido-exhibit'.
- 'always))
- (setq ido-text-init ido-text)
- (setq ido-exit 'refresh)
- (exit-minibuffer)))
- (defun ido-reread-directory ()
- "Read current directory again.
- May be useful if cached version is no longer valid, but directory
- timestamp has not changed (e.g. with FTP or on Windows)."
- (interactive)
- (if (and ido-mode (memq ido-cur-item '(file dir)))
- (progn
- (if (ido-is-unc-root)
- (setq ido-unc-hosts-cache t)
- (ido-remove-cached-dir ido-current-directory))
- (setq ido-text-init ido-text)
- (setq ido-rotate-temp t)
- (setq ido-exit 'refresh)
- (exit-minibuffer))))
- (defun ido-exit-minibuffer ()
- "Exit minibuffer, but make sure we have a match if one is needed."
- (interactive)
- (if (and (or (not ido-require-match)
- (if (memq ido-require-match '(confirm confirm-after-completion))
- (if (or (eq ido-cur-item 'dir)
- (eq last-command this-command))
- t
- (setq ido-show-confirm-message t)
- nil))
- (ido-existing-item-p))
- (not ido-incomplete-regexp))
- (exit-minibuffer)))
- (defun ido-select-text ()
- "Select the buffer or file named by the prompt.
- If no buffer or file exactly matching the prompt exists, maybe create a new one."
- (interactive)
- (setq ido-exit 'takeprompt)
- (exit-minibuffer))
- (defun ido-fallback-command ()
- "Fallback to non-Ido version of current command."
- (interactive)
- (let ((i (length ido-text)))
- (while (> i 0)
- (push (aref ido-text (setq i (1- i))) unread-command-events)))
- (setq ido-exit 'fallback)
- (exit-minibuffer))
- (defun ido-enter-find-file ()
- "Drop into `find-file' from buffer switching."
- (interactive)
- (setq ido-exit 'find-file)
- (exit-minibuffer))
- (defun ido-enter-switch-buffer ()
- "Drop into `ido-switch-buffer' from file switching."
- (interactive)
- (setq ido-exit 'switch-to-buffer)
- (exit-minibuffer))
- (defun ido-enter-dired ()
- "Drop into `dired' from file switching."
- (interactive)
- (setq ido-exit 'dired)
- (exit-minibuffer))
- (defun ido-enter-insert-buffer ()
- "Drop into `insert-buffer' from insert file."
- (interactive)
- (setq ido-exit 'insert-buffer)
- (exit-minibuffer))
- (defun ido-enter-insert-file ()
- "Drop into `insert-file' from insert buffer."
- (interactive)
- (setq ido-exit 'insert-file)
- (exit-minibuffer))
- (defun ido-up-directory (&optional clear)
- "Go up one directory level."
- (interactive "P")
- (setq ido-text-init (if clear nil ido-text))
- (setq ido-exit 'updir)
- (setq ido-rotate-temp t)
- (exit-minibuffer))
- (defun ido-delete-backward-updir (count)
- "Delete char backwards, or at beginning of buffer, go up one level."
- (interactive "P")
- (cond
- ((= (minibuffer-prompt-end) (point))
- (if (not count)
- (ido-up-directory t)))
- ((and ido-pre-merge-state (string-equal (car ido-pre-merge-state) ido-text))
- (ido-undo-merge-work-directory (substring ido-text 0 -1) t t))
- ((eq this-original-command 'viper-backward-char)
- (funcall this-original-command (prefix-numeric-value count)))
- ((eq this-original-command 'viper-del-backward-char-in-insert)
- (funcall this-original-command))
- (t
- (delete-char (- (prefix-numeric-value count))))))
- (defun ido-delete-backward-word-updir (count)
- "Delete all chars backwards, or at beginning of buffer, go up one level."
- (interactive "P")
- (if (= (minibuffer-prompt-end) (point))
- (if (not count)
- (ido-up-directory t))
- (if (eq this-original-command 'viper-delete-backward-word)
- (funcall this-original-command (prefix-numeric-value count))
- (backward-kill-word (prefix-numeric-value count)))))
- (defun ido-get-work-directory (&optional incr must-match)
- (let ((n (length ido-work-directory-list))
- (i ido-work-directory-index)
- (j 0)
- dir)
- (if (or (not ido-text) (= (length ido-text) 0))
- (setq must-match nil))
- (while (< j n)
- (setq i (+ i incr)
- j (1+ j))
- (if (> incr 0)
- (if (>= i n) (setq i 0))
- (if (< i 0) (setq i (1- n))))
- (setq dir (nth i ido-work-directory-list))
- (if (and dir
- (not (equal dir ido-current-directory))
- (file-directory-p dir)
- (or (not must-match)
- ;; TODO. check for nonreadable and too-big.
- (ido-set-matches-1
- (if (eq ido-cur-item 'file)
- (ido-make-file-list-1 dir)
- (ido-make-dir-list-1 dir)))))
- (setq j n)
- (setq dir nil)))
- (if dir
- (setq ido-work-directory-index i))
- dir))
- (defun ido-prev-work-directory ()
- "Change to next working directory in list."
- (interactive)
- (let ((dir (ido-get-work-directory 1 ido-work-directory-match-only)))
- (when dir
- (ido-set-current-directory dir)
- (setq ido-exit 'refresh)
- (setq ido-text-init ido-text)
- (setq ido-rotate-temp t)
- (exit-minibuffer))))
- (defun ido-next-work-directory ()
- "Change to previous working directory in list."
- (interactive)
- (let ((dir (ido-get-work-directory -1 ido-work-directory-match-only)))
- (when dir
- (ido-set-current-directory dir)
- (setq ido-exit 'refresh)
- (setq ido-text-init ido-text)
- (setq ido-rotate-temp t)
- (exit-minibuffer))))
- (defun ido-merge-work-directories ()
- "Search (and merge) work directories for files matching the current input string."
- (interactive)
- (setq ido-use-merged-list t ido-try-merged-list t)
- (setq ido-exit 'refresh)
- (setq ido-text-init ido-text)
- (setq ido-rotate-temp t)
- (exit-minibuffer))
- (defun ido-wide-find-file (&optional file)
- "Prompt for FILE to search for using `find', starting from current directory."
- (interactive)
- (unless file
- (let ((enable-recursive-minibuffers t))
- (setq file
- (condition-case nil
- (read-string (concat "Wide find file: " ido-current-directory) ido-text)
- (quit "")))))
- (when (> (length file) 0)
- (setq ido-use-merged-list t ido-try-merged-list 'wide)
- (setq ido-exit 'refresh)
- (setq ido-text-init file)
- (setq ido-rotate-temp t)
- (exit-minibuffer)))
- (defun ido-wide-find-dir (&optional dir)
- "Prompt for DIR to search for using `find', starting from current directory."
- (interactive)
- (unless dir
- (let ((enable-recursive-minibuffers t))
- (setq dir
- (condition-case nil
- (read-string (concat "Wide find directory: " ido-current-directory) ido-text)
- (quit "")))))
- (when (> (length dir) 0)
- (setq ido-use-merged-list t ido-try-merged-list 'wide)
- (setq ido-exit 'refresh)
- (setq ido-text-init (ido-final-slash dir t))
- (setq ido-rotate-temp t)
- (exit-minibuffer)))
- (defun ido-wide-find-dir-or-delete-dir (&optional _dir)
- "Prompt for DIR to search for using `find', starting from current directory.
- If input stack is non-empty, delete current directory component."
- (interactive)
- (if ido-input-stack
- (ido-delete-backward-word-updir 1)
- (ido-wide-find-dir)))
- (defun ido-take-first-match ()
- "Use first matching item as input text."
- (interactive)
- (when ido-matches
- (setq ido-text-init (ido-name (car ido-matches)))
- (setq ido-exit 'refresh)
- (exit-minibuffer)))
- (defun ido-push-dir ()
- "Move to previous directory in file name, push current input on stack."
- (interactive)
- (setq ido-exit 'push)
- (exit-minibuffer))
- (defun ido-push-dir-first ()
- "Move to previous directory in file name, push first match on stack."
- (interactive)
- (if ido-matches
- (setq ido-text (ido-name (car ido-matches))))
- (setq ido-exit 'push)
- (exit-minibuffer))
- (defun ido-pop-dir (arg)
- "Pop directory from input stack back to input.
- With \\[universal-argument], pop all elements."
- (interactive "P")
- (when ido-input-stack
- (setq ido-exit (if arg 'pop-all 'pop))
- (exit-minibuffer)))
- (defun ido-wide-find-file-or-pop-dir (arg)
- (interactive "P")
- (if ido-input-stack
- (ido-pop-dir arg)
- (ido-wide-find-file)))
- (defun ido-make-directory (&optional dir)
- "Prompt for DIR to create in current directory."
- (interactive)
- (unless dir
- (let ((enable-recursive-minibuffers t))
- (setq dir
- (read-string (concat "Make directory: " ido-current-directory) ido-text))))
- (when (> (length dir) 0)
- (setq dir (concat ido-current-directory dir))
- (unless (file-exists-p dir)
- (make-directory dir t)
- (ido-set-current-directory dir)
- (setq ido-exit 'refresh)
- (setq ido-text-init nil)
- (setq ido-rotate-temp t)
- (exit-minibuffer))))
- (defun ido-get-work-file (incr)
- (let ((n (length ido-work-file-list))
- (i (+ ido-work-file-index incr))
- name)
- (if (> incr 0)
- (if (>= i n) (setq i 0))
- (if (< i 0) (setq i (1- n))))
- (setq name (nth i ido-work-file-list))
- (setq ido-work-file-index i)
- name))
- (defun ido-prev-work-file ()
- "Change to next working file name in list."
- (interactive)
- (let ((name (ido-get-work-file 1)))
- (when name
- (setq ido-text-init name)
- (setq ido-exit 'refresh)
- (exit-minibuffer))))
- (defun ido-next-work-file ()
- "Change to previous working file name in list."
- (interactive)
- (let ((name (ido-get-work-file -1)))
- (when name
- (setq ido-text-init name)
- (setq ido-exit 'refresh)
- (exit-minibuffer))))
- (defun ido-copy-current-file-name (all)
- "Insert file name of current buffer.
- If repeated, insert text from buffer instead."
- (interactive "P")
- (let* ((bfname (or (buffer-file-name ido-entry-buffer)
- (buffer-name ido-entry-buffer)))
- (name (and bfname (file-name-nondirectory bfname))))
- (when name
- (setq ido-text-init
- (if (or all
- (eq last-command this-command)
- (not (equal (file-name-directory bfname) ido-current-directory))
- (not (string-match "\\.[^.]*\\'" name)))
- name
- (substring name 0 (1+ (match-beginning 0)))))
- (setq ido-exit 'refresh
- ido-try-merged-list nil)
- (exit-minibuffer))))
- (defun ido-copy-current-word (_all)
- "Insert current word (file or directory name) from current buffer."
- (interactive "P")
- (let ((word (with-current-buffer ido-entry-buffer
- (let ((p (point)) start-line end-line start-name)
- (if (and mark-active (/= p (mark)))
- (setq start-name (mark))
- (beginning-of-line)
- (setq start-line (point))
- (end-of-line)
- (setq end-line (point))
- (goto-char p)
- (if (re-search-backward "[^-_a-zA-Z0-9:./\\~@]" start-line 1)
- (forward-char 1))
- (setq start-name (point))
- (re-search-forward "[-_a-zA-Z0-9:./\\~@]*" end-line 1)
- (if (= start-name (point))
- (setq start-name nil)))
- (and start-name
- (buffer-substring-no-properties start-name (point)))))))
- (if (cond
- ((not word) nil)
- ((string-match "\\`[~/]" word)
- (setq ido-text-init word
- ido-try-merged-list nil
- ido-exit 'chdir))
- ((string-match "/" word)
- (setq ido-text-init (concat ido-current-directory word)
- ido-try-merged-list nil
- ido-exit 'chdir))
- (t
- (setq ido-text-init word
- ido-try-merged-list nil
- ido-exit 'refresh)))
- (exit-minibuffer))))
- (defun ido-next-match ()
- "Put first element of `ido-matches' at the end of the list."
- (interactive)
- (if ido-matches
- (let ((next (cadr ido-matches)))
- (setq ido-cur-list (ido-chop ido-cur-list next))
- (setq ido-matches (ido-chop ido-matches next))
- (setq ido-rescan nil))))
- (defun ido-prev-match ()
- "Put last element of `ido-matches' at the front of the list."
- (interactive)
- (if ido-matches
- (let ((prev (car (last ido-matches))))
- (setq ido-cur-list (ido-chop ido-cur-list prev))
- (setq ido-matches (ido-chop ido-matches prev))
- (setq ido-rescan nil))))
- (defun ido-next-match-dir ()
- "Find next directory in match list.
- If work directories have been merged, cycle through directories for
- first matching file."
- (interactive)
- (if ido-use-merged-list
- (if ido-matches
- (let* ((elt (car ido-matches))
- (dirs (cdr elt)))
- (when (> (length dirs) 1)
- (setcdr elt (ido-chop dirs (cadr dirs))))
- (setq ido-rescan nil)))
- (let ((cnt (length ido-matches))
- (i 1))
- (while (and (< i cnt) (not (ido-final-slash (nth i ido-matches))))
- (setq i (1+ i)))
- (if (< i cnt)
- (setq ido-cur-list (ido-chop ido-cur-list (nth i ido-matches)))))))
- (defun ido-prev-match-dir ()
- "Find previous directory in match list.
- If work directories have been merged, cycle through directories
- for first matching file."
- (interactive)
- (if ido-use-merged-list
- (if ido-matches
- (let* ((elt (car ido-matches))
- (dirs (cdr elt)))
- (when (> (length dirs) 1)
- (setcdr elt (ido-chop dirs (car (last dirs)))))
- (setq ido-rescan nil)))
- (let* ((cnt (length ido-matches))
- (i (1- cnt)))
- (while (and (> i 0) (not (ido-final-slash (nth i ido-matches))))
- (setq i (1- i)))
- (if (> i 0)
- (setq ido-cur-list (ido-chop ido-cur-list (nth i ido-matches)))))))
- (defun ido-restrict-to-matches (&optional removep)
- "Set current item list to the currently matched items.
- When argument REMOVEP is non-nil, the currently matched items are
- instead removed from the current item list."
- (interactive "P")
- (when ido-matches
- (setq ido-cur-list (if removep
- ;; An important feature is to preserve the
- ;; order of the elements.
- (seq-difference ido-cur-list ido-matches)
- ido-matches)
- ido-matches ido-cur-list
- ido-text-init ""
- ido-rescan nil
- ido-exit 'keep)
- (exit-minibuffer)))
- (defun ido-chop (items elem)
- "Remove all elements before ELEM and put them at the end of ITEMS."
- (let ((ret nil)
- (next nil)
- (sofar nil))
- (while (not ret)
- (setq next (car items))
- (if (equal next elem)
- (setq ret (append items (nreverse sofar)))
- ;; else
- (progn
- (setq items (cdr items))
- (setq sofar (cons next sofar)))))
- ret))
- (defun ido-name (item)
- ;; Return file name for current item, whether in a normal list
- ;; or a merged work directory list.
- (if (consp item) (car item) item))
- ;;; CREATE LIST OF ALL CURRENT FILES
- (defun ido-all-completions ()
- ;; Return unsorted list of all completions.
- (let ((ido-process-ignore-lists nil)
- (ido-directory-too-big nil))
- (cond
- ((eq ido-cur-item 'file)
- (ido-make-file-list-1 ido-current-directory))
- ((eq ido-cur-item 'dir)
- (ido-make-dir-list-1 ido-current-directory))
- ((eq ido-cur-item 'buffer)
- (ido-make-buffer-list-1))
- ((eq ido-cur-item 'list)
- ido-choice-list)
- (t nil))))
- ;; File list sorting
- (defun ido-file-lessp (a b)
- ;; Simple compare two file names.
- (string-lessp (ido-no-final-slash a) (ido-no-final-slash b)))
- (defun ido-file-extension-lessp (a b)
- ;; Compare file names according to ido-file-extensions-order list.
- (let ((n (compare-strings a 0 nil b 0 nil nil))
- lessp p)
- (if (eq n t)
- nil
- (if (< n 0)
- (setq n (1- (- n))
- p a a b b p
- lessp t)
- (setq n (1- n)))
- (cond
- ((= n 0)
- lessp)
- ((= (aref a n) ?.)
- (ido-file-extension-aux a b n lessp))
- (t
- (while (and (> n 2) (/= (aref a n) ?.))
- (setq n (1- n)))
- (if (> n 1)
- (ido-file-extension-aux a b n lessp)
- lessp))))))
- (defun ido-file-extension-aux (a b n lessp)
- (let ((oa (ido-file-extension-order a n))
- (ob (ido-file-extension-order b n)))
- (cond
- ((and oa ob)
- (cond
- ((= oa ob)
- lessp)
- (lessp
- (> oa ob))
- (t
- (< oa ob))))
- (oa
- (not lessp))
- (ob
- lessp)
- (t
- lessp))))
- (defun ido-file-extension-order (s n)
- (let ((l ido-file-extensions-order)
- (i 0) o do)
- (while l
- (cond
- ((eq (car l) t)
- (setq do i
- l (cdr l)))
- ((eq (compare-strings s n nil (car l) 0 nil nil) t)
- (setq o i
- l nil))
- (t
- (setq l (cdr l))))
- (setq i (1+ i)))
- (or o do)))
- (defun ido-sort-merged-list (items promote)
- ;; Input is list of ("file" . "dir") cons cells.
- ;; Output is sorted list of ("file "dir" ...) lists
- (let ((l (sort items (lambda (a b) (string-lessp (car b) (car a)))))
- res a cur)
- (while l
- (setq a (car l)
- l (cdr l))
- (if (and res (string-equal (car (car res)) (car a)))
- (progn
- (setcdr (car (if cur (cdr res) res)) (cons (cdr a) (cdr (car res))))
- (if (and promote (string-equal ido-current-directory (cdr a)))
- (setq cur t)))
- (setq res (cons (list (car a) (cdr a)) res)
- cur nil)))
- res))
- (defun ido-wide-find-dirs-or-files (dir file &optional prefix finddir)
- ;; As ido-run-find-command, but returns a list of cons pairs ("file" . "dir")
- (let ((filenames
- (delq nil
- (mapcar (lambda (name)
- (unless (ido-ignore-item-p name ido-ignore-files t)
- name))
- (split-string
- (shell-command-to-string
- (concat "find "
- (shell-quote-argument dir)
- (if ido-case-fold " -iname " " -name ")
- (shell-quote-argument
- (concat (if prefix "" "*") file "*"))
- " -type " (if finddir "d" "f") " -print"))))))
- filename d f
- res)
- (while filenames
- (setq filename (car filenames)
- filenames (cdr filenames))
- (if (and (file-name-absolute-p filename)
- (file-exists-p filename))
- (setq d (file-name-directory filename)
- f (file-name-nondirectory filename)
- res (cons (cons (if finddir (ido-final-slash f t) f) d) res))))
- res))
- (defun ido-flatten-merged-list (items)
- "Create a list of directory names based on a merged directory list."
- (let (res)
- (while items
- (let* ((item (car items))
- (file (car item))
- (dirs (cdr item)))
- (while dirs
- (setq res (cons (concat (car dirs) file) res)
- dirs (cdr dirs))))
- (setq items (cdr items)))
- res))
- (defun ido-make-merged-file-list-1 (text auto wide)
- (let (res)
- (if (and (ido-final-slash text) ido-dir-file-cache)
- (if wide
- (setq res (ido-wide-find-dirs-or-files
- ido-current-directory (substring text 0 -1) ido-enable-prefix t))
- ;; Use list of cached directories
- (let ((re (concat (regexp-quote (substring text 0 -1)) "[^/:]*/\\'"))
- (dirs ido-dir-file-cache)
- dir b d f)
- (if nil ;; simple
- (while dirs
- (setq dir (car (car dirs))
- dirs (cdr dirs))
- (when (and (string-match re dir)
- (not (ido-ignore-item-p dir ido-ignore-directories-merge))
- (file-directory-p dir))
- (setq b (substring dir 0 -1)
- f (concat (file-name-nondirectory b) "/")
- d (file-name-directory b)
- res (cons (cons f d) res))))
- (while dirs
- (setq dir (car dirs)
- d (car dir)
- dirs (cdr dirs))
- (when (not (ido-ignore-item-p d ido-ignore-directories-merge))
- (setq dir (cdr (cdr dir)))
- (while dir
- (setq f (car dir)
- dir (cdr dir))
- (if (and (string-match re f)
- (not (ido-ignore-item-p f ido-ignore-directories)))
- (setq res (cons (cons f d) res)))))
- (if (and auto (input-pending-p))
- (setq dirs nil
- res t))))))
- (if wide
- (setq res (ido-wide-find-dirs-or-files
- ido-current-directory text ido-enable-prefix nil))
- (let ((ido-text text)
- (dirs ido-work-directory-list)
- (must-match (and text (> (length text) 0)))
- dir fl)
- (if (and auto (not (member ido-current-directory dirs)))
- (setq dirs (cons ido-current-directory dirs)))
- (while dirs
- (setq dir (car dirs)
- dirs (cdr dirs))
- (when (and dir (stringp dir)
- (or ido-merge-ftp-work-directories
- (not (ido-is-ftp-directory dir)))
- (file-directory-p dir)
- ;; TODO. check for nonreadable and too-big.
- (setq fl (if (eq ido-cur-item 'file)
- (ido-make-file-list-1 dir t)
- (ido-make-dir-list-1 dir t))))
- (if must-match
- (setq fl (ido-set-matches-1 fl)))
- (if fl
- (setq res (nconc fl res))))
- (if (and auto (input-pending-p))
- (setq dirs nil
- res t))))))
- res))
- (defun ido-make-merged-file-list (text auto wide)
- (let (res)
- (message "Searching for `%s'...." text)
- (condition-case nil
- (if (eq t (setq res
- (while-no-input
- (ido-make-merged-file-list-1 text auto wide))))
- (setq res 'input-pending-p))
- (quit
- (setq res t
- ido-try-merged-list nil
- ido-use-merged-list nil)))
- (when (and res (listp res))
- (setq res (ido-sort-merged-list res auto)))
- (when (and (or ido-rotate-temp ido-rotate-file-list-default)
- (listp res)
- (> (length text) 0))
- (let ((elt (assoc text res)))
- (when (and elt (not (eq elt (car res))))
- (setq res (delq elt res))
- (setq res (cons elt res)))))
- (message nil)
- res))
- (defun ido-make-buffer-list-1 (&optional frame visible)
- "Return list of non-ignored buffer names."
- (delq nil
- (mapcar
- (lambda (x)
- (let ((name (buffer-name x)))
- (if (not (or (ido-ignore-item-p name ido-ignore-buffers) (member name visible)))
- name)))
- (buffer-list frame))))
- (defun ido-make-buffer-list (default)
- "Return the current list of buffers.
- Currently visible buffers are put at the end of the list.
- The hook `ido-make-buffer-list-hook' is run after the list has been
- created to allow the user to further modify the order of the buffer names
- in this list. If DEFAULT is non-nil, and corresponds to an existing buffer,
- it is put to the start of the list."
- (let* ((ido-current-buffers (ido-get-buffers-in-frames 'current))
- (ido-temp-list (ido-make-buffer-list-1 (selected-frame) ido-current-buffers)))
- (if ido-temp-list
- (nconc ido-temp-list ido-current-buffers)
- (setq ido-temp-list ido-current-buffers))
- (if default
- (setq ido-temp-list
- (cons default (delete default ido-temp-list))))
- (if (bound-and-true-p ido-enable-virtual-buffers)
- (ido-add-virtual-buffers-to-list))
- (run-hooks 'ido-make-buffer-list-hook)
- ido-temp-list))
- (defun ido-add-virtual-buffers-to-list ()
- "Add recently visited files, and bookmark files, to the buffer list.
- This is to make them appear as if they were \"virtual buffers\"."
- ;; If no buffers matched, and virtual buffers are being used, then
- ;; consult the list of past visited files, to see if we can find
- ;; the file which the user might thought was still open.
- (unless recentf-mode (recentf-mode 1))
- (setq ido-virtual-buffers nil)
- (let (name)
- (dolist (head (append
- recentf-list
- (and (fboundp 'bookmark-get-filename)
- (delq nil (mapcar #'bookmark-get-filename
- (bound-and-true-p bookmark-alist))))))
- (setq name (file-name-nondirectory head))
- ;; In case HEAD is a directory with trailing /. See bug#14552.
- (when (equal name "")
- (setq name (file-name-nondirectory (directory-file-name head))))
- (when (equal name "")
- (setq name head))
- (and (not (equal name ""))
- (null (let (file-name-handler-alist) (get-file-buffer head)))
- (not (assoc name ido-virtual-buffers))
- (not (member name ido-temp-list))
- (not (ido-ignore-item-p name ido-ignore-buffers))
- ;;(file-exists-p head)
- (push (cons name head) ido-virtual-buffers))))
- (when ido-virtual-buffers
- (if ido-use-faces
- (dolist (comp ido-virtual-buffers)
- (put-text-property 0 (length (car comp))
- 'face 'ido-virtual
- (car comp))))
- (setq ido-temp-list
- (nconc ido-temp-list
- (nreverse (mapcar #'car ido-virtual-buffers))))))
- (defun ido-make-choice-list (default)
- "Return the current list of choices.
- If DEFAULT is non-nil, and corresponds to an element of choices,
- it is put to the start of the list."
- (let ((ido-temp-list ido-choice-list))
- (if default
- (progn
- (setq ido-temp-list
- (delete default ido-temp-list))
- (setq ido-temp-list
- (cons default ido-temp-list))))
- ; (run-hooks 'ido-make-choice-list-hook)
- ido-temp-list))
- (defun ido-to-end (items)
- "Move the elements from ITEMS to the end of `ido-temp-list'."
- (mapc
- (lambda (elem)
- (setq ido-temp-list (delq elem ido-temp-list)))
- items)
- (if ido-temp-list
- (nconc ido-temp-list items)
- (setq ido-temp-list items)))
- (defun ido-file-name-all-completions-1 (dir)
- (cond
- ((ido-nonreadable-directory-p dir) '())
- ;; do not check (ido-directory-too-big-p dir) here.
- ;; Caller must have done that if necessary.
- ((and ido-enable-tramp-completion
- (string-match "\\`/[^/]+[:@]\\'" dir))
- ;; Strip method:user@host: part of tramp completions.
- ;; Tramp completions do not include leading slash.
- (let* ((len (1- (length dir)))
- (compl
- (or ;; We do not want to be disturbed by "File does not
- ;; exist" errors.
- (ignore-errors (file-name-all-completions "" dir))
- ;; work around bug in ange-ftp.
- ;; /ftp:user@host: => nil
- ;; /ftp:user@host:./ => ok
- (and
- (not (string= "/ftp:" dir))
- (file-remote-p dir)
- ;; tramp-ftp-file-name-p is available only when tramp
- ;; has been loaded.
- (fboundp 'tramp-ftp-file-name-p)
- (funcall 'tramp-ftp-file-name-p dir)
- (string-match ":\\'" dir)
- (file-name-all-completions "" (concat dir "./"))))))
- (if (and compl
- (> (length (car compl)) len)
- (string= (substring (car compl) 0 len) (substring dir 1)))
- (mapcar (lambda (c) (substring c len)) compl)
- compl)))
- (t
- (file-name-all-completions "" dir))))
- (defun ido-file-name-all-completions (dir)
- "Return name of all files in DIR.
- Uses and updates `ido-dir-file-cache'."
- (cond
- ((ido-is-unc-root dir)
- (mapcar
- (lambda (host)
- (if (string-match "/\\'" host) host (concat host "/")))
- (ido-unc-hosts t)))
- ((and (numberp ido-max-dir-file-cache) (> ido-max-dir-file-cache 0)
- (stringp dir) (> (length dir) 0)
- (ido-may-cache-directory dir))
- (let* ((cached (assoc dir ido-dir-file-cache))
- (ctime (nth 1 cached))
- (ftp (ido-is-ftp-directory dir))
- (unc (ido-is-unc-host dir))
- (attr (if (or ftp unc) nil (file-attributes dir)))
- (mtime (nth 5 attr))
- valid)
- (when cached ; should we use the cached entry ?
- (cond
- (ftp
- (setq valid (and (eq (car ctime) 'ftp)
- (ido-cache-ftp-valid (cdr ctime)))))
- (unc
- (setq valid (and (eq (car ctime) 'unc)
- (ido-cache-unc-valid (cdr ctime)))))
- (t
- (if attr
- (setq valid (and (= (car ctime) (car mtime))
- (= (car (cdr ctime)) (car (cdr mtime))))))))
- (unless valid
- (setq ido-dir-file-cache (delq cached ido-dir-file-cache)
- cached nil)))
- (unless cached
- (cond
- (unc
- (setq mtime (cons 'unc (ido-time-stamp))))
- ((and ftp (file-readable-p dir))
- (setq mtime (cons 'ftp (ido-time-stamp)))))
- (if mtime
- (setq cached (cons dir (cons mtime (ido-file-name-all-completions-1 dir)))
- ido-dir-file-cache (cons cached ido-dir-file-cache)))
- (if (> (length ido-dir-file-cache) ido-max-dir-file-cache)
- (setcdr (nthcdr (1- ido-max-dir-file-cache) ido-dir-file-cache) nil)))
- (and cached
- (cdr (cdr cached)))))
- (t
- (ido-file-name-all-completions-1 dir))))
- (defun ido-remove-cached-dir (dir)
- "Remove DIR from `ido-dir-file-cache'."
- (if (and ido-dir-file-cache
- (stringp dir) (> (length dir) 0))
- (let ((cached (assoc dir ido-dir-file-cache)))
- (if cached
- (setq ido-dir-file-cache (delq cached ido-dir-file-cache))))))
- (defun ido-make-file-list-1 (dir &optional merged)
- "Return list of non-ignored files in DIR
- If MERGED is non-nil, each file is cons'ed with DIR."
- (and (or (ido-is-tramp-root dir) (ido-is-unc-root dir)
- (file-directory-p dir))
- (delq nil
- (mapcar
- (lambda (name)
- (if (not (ido-ignore-item-p name ido-ignore-files t))
- (if merged (cons name dir) name)))
- (ido-file-name-all-completions dir)))))
- (defun ido-make-file-list (default)
- "Return the current list of files.
- Currently visible files are put at the end of the list.
- The hook `ido-make-file-list-hook' is run after the list has been
- created to allow the user to further modify the order of the file names
- in this list."
- (let ((ido-temp-list (ido-make-file-list-1 ido-current-directory)))
- (setq ido-temp-list (sort ido-temp-list
- (if ido-file-extensions-order
- #'ido-file-extension-lessp
- #'ido-file-lessp)))
- (unless (ido-is-tramp-root ido-current-directory)
- (let ((default-directory ido-current-directory))
- (ido-to-end ;; move ftp hosts and visited files to end
- (delq nil (mapcar
- (lambda (x) (if (or (and (string-match ".:\\'" x)
- (not (ido-local-file-exists-p x)))
- (and (not (ido-final-slash x))
- (let (file-name-handler-alist)
- (get-file-buffer x)))) x))
- ido-temp-list)))))
- (ido-to-end ;; move . files to end
- (delq nil (mapcar
- (lambda (x) (if (string-match "\\`\\." x) x))
- ido-temp-list)))
- (if (and default (member default ido-temp-list))
- (if (or ido-rotate-temp ido-rotate-file-list-default)
- (unless (equal default (car ido-temp-list))
- (let ((l ido-temp-list) k)
- (while (and l (cdr l) (not (equal default (car (cdr l)))))
- (setq l (cdr l)))
- (setq k (cdr l))
- (setcdr l nil)
- (nconc k ido-temp-list)
- (setq ido-temp-list k)))
- (setq ido-temp-list
- (delete default ido-temp-list))
- (setq ido-temp-list
- (cons default ido-temp-list))))
- (when ido-show-dot-for-dired
- (setq ido-temp-list (delete "." ido-temp-list))
- (setq ido-temp-list (cons "." ido-temp-list)))
- (run-hooks 'ido-make-file-list-hook)
- ido-temp-list))
- (defun ido-make-dir-list-1 (dir &optional merged)
- "Return list of non-ignored subdirs in DIR.
- If MERGED is non-nil, each subdir is cons'ed with DIR."
- (and (or (ido-is-tramp-root dir) (file-directory-p dir))
- (delq nil
- (mapcar
- (lambda (name)
- (and (ido-final-slash name) (not (ido-ignore-item-p name ido-ignore-directories))
- (if merged (cons name dir) name)))
- (ido-file-name-all-completions dir)))))
- (defun ido-make-dir-list (default)
- "Return the current list of directories.
- The hook `ido-make-dir-list-hook' is run after the list has been
- created to allow the user to further modify the order of the
- directory names in this list."
- (let ((ido-temp-list (ido-make-dir-list-1 ido-current-directory)))
- (setq ido-temp-list (sort ido-temp-list #'ido-file-lessp))
- (ido-to-end ;; move . files to end
- (delq nil (mapcar
- (lambda (x) (if (string-equal (substring x 0 1) ".") x))
- ido-temp-list)))
- (if (and default (member default ido-temp-list))
- (if (or ido-rotate-temp ido-rotate-file-list-default)
- (unless (equal default (car ido-temp-list))
- (let ((l ido-temp-list) k)
- (while (and l (cdr l) (not (equal default (car (cdr l)))))
- (setq l (cdr l)))
- (setq k (cdr l))
- (setcdr l nil)
- (nconc k ido-temp-list)
- (setq ido-temp-list k)))
- (setq ido-temp-list
- (delete default ido-temp-list))
- (setq ido-temp-list
- (cons default ido-temp-list))))
- (setq ido-temp-list (delete "." ido-temp-list))
- (unless ido-input-stack
- (setq ido-temp-list (cons "." ido-temp-list)))
- (run-hooks 'ido-make-dir-list-hook)
- ido-temp-list))
- ;; List of the files visible in the current frame.
- (defvar ido-bufs-in-frame)
- (defun ido-get-buffers-in-frames (&optional current)
- "Return the list of buffers that are visible in the current frame.
- If optional argument CURRENT is given, restrict searching to the current
- frame, rather than all frames, regardless of value of `ido-all-frames'."
- (let ((ido-bufs-in-frame nil))
- (walk-windows 'ido-get-bufname nil
- (if current
- nil
- ido-all-frames))
- ido-bufs-in-frame))
- (defun ido-get-bufname (win)
- "Used by `ido-get-buffers-in-frames' to walk through all windows."
- (let ((buf (buffer-name (window-buffer win))))
- (unless (or (member buf ido-bufs-in-frame)
- (member buf ido-ignore-item-temp-list))
- ;; Only add buf if it is not already in list.
- ;; This prevents same buf in two different windows being
- ;; put into the list twice.
- (setq ido-bufs-in-frame
- (cons buf ido-bufs-in-frame)))))
- ;;; FIND MATCHING ITEMS
- (defun ido-set-matches-1 (items &optional do-full)
- "Return list of matches in ITEMS."
- (let* ((case-fold-search ido-case-fold)
- (slash (and (not ido-enable-prefix) (ido-final-slash ido-text)))
- (text (if slash (substring ido-text 0 -1) ido-text))
- (rex0 (if ido-enable-regexp text (regexp-quote text)))
- (rexq (concat rex0 (if slash ".*/" "")))
- (re (if ido-enable-prefix (concat "\\`" rexq) rexq))
- (full-re (and do-full
- (not (and (eq ido-cur-item 'buffer)
- ido-buffer-disable-smart-matches))
- (not ido-enable-regexp)
- (not (string-match "$\\'" rex0))
- (concat "\\`" rex0 (if slash "/" "") "\\'")))
- (suffix-re (and do-full slash
- (not (and (eq ido-cur-item 'buffer)
- ido-buffer-disable-smart-matches))
- (not ido-enable-regexp)
- (not (string-match "$\\'" rex0))
- (concat rex0 "/\\'")))
- (prefix-re (and full-re (not ido-enable-prefix)
- (concat "\\`" rexq)))
- (non-prefix-dot (or (not ido-enable-dot-prefix)
- (not ido-process-ignore-lists)
- ido-enable-prefix
- (= (length ido-text) 0)))
- full-matches suffix-matches prefix-matches matches)
- (setq ido-incomplete-regexp nil)
- (condition-case error
- (mapc
- (lambda (item)
- (let ((name (ido-name item)))
- (if (and (or non-prefix-dot
- (and (> (length name) 0)
- (if (= (aref ido-text 0) ?.)
- (= (aref name 0) ?.)
- (/= (aref name 0) ?.))))
- (string-match re name))
- (cond
- ((and (eq ido-cur-item 'buffer)
- (or (not (stringp ido-default-item))
- (not (string= name ido-default-item)))
- (string= name (buffer-name ido-entry-buffer)))
- (setq matches (cons item matches)))
- ((and full-re (string-match full-re name))
- (setq full-matches (cons item full-matches)))
- ((and suffix-re (string-match suffix-re name))
- (setq suffix-matches (cons item suffix-matches)))
- ((and prefix-re (string-match prefix-re name))
- (setq prefix-matches (cons item prefix-matches)))
- (t (setq matches (cons item matches))))))
- t)
- items)
- (invalid-regexp
- (setq ido-incomplete-regexp t
- ;; Consider the invalid regexp message internally as a
- ;; special-case single match, and handle appropriately
- ;; elsewhere.
- matches (cdr error))))
- (when prefix-matches
- (ido-trace "prefix match" prefix-matches)
- ;; Bug#2042.
- (setq matches (nconc prefix-matches matches)))
- (when suffix-matches
- (ido-trace "suffix match" (list text suffix-re suffix-matches))
- (setq matches (nconc suffix-matches matches)))
- (when full-matches
- (ido-trace "full match" (list text full-re full-matches))
- (setq matches (nconc full-matches matches)))
- (when (and (null matches)
- ido-enable-flex-matching
- (> (length ido-text) 1)
- (not ido-enable-regexp))
- (setq re (concat (regexp-quote (string (aref ido-text 0)))
- (mapconcat (lambda (c)
- (concat "[^" (string c) "]*"
- (regexp-quote (string c))))
- (substring ido-text 1) "")))
- (if ido-enable-prefix
- (setq re (concat "\\`" re)))
- (mapc
- (lambda (item)
- (let ((name (ido-name item)))
- (if (string-match re name)
- (setq matches (cons item matches)))))
- items))
- (delete-consecutive-dups matches t)))
- (defun ido-set-matches ()
- "Set `ido-matches' to the list of items matching prompt."
- (when ido-rescan
- (setq ido-matches (ido-set-matches-1 (reverse ido-cur-list) (not ido-rotate))
- ido-rotate nil)))
- (defun ido-ignore-item-p (name re-list &optional ignore-ext)
- "Return t if the buffer or file NAME should be ignored."
- (or (member name ido-ignore-item-temp-list)
- (and
- ido-process-ignore-lists re-list
- (save-match-data
- (let ((ext-list (and ignore-ext ido-ignore-extensions
- completion-ignored-extensions))
- (case-fold-search ido-case-fold)
- ignorep nextstr
- (flen (length name)) slen)
- (while ext-list
- (setq nextstr (car ext-list))
- (if (cond
- ((stringp nextstr)
- (and (>= flen (setq slen (length nextstr)))
- (string-equal (substring name (- flen slen)) nextstr)))
- ((functionp nextstr) (funcall nextstr name))
- (t nil))
- (setq ignorep t
- ext-list nil
- re-list nil)
- (setq ext-list (cdr ext-list))))
- (while re-list
- (setq nextstr (car re-list))
- (if (cond
- ((stringp nextstr) (string-match nextstr name))
- ((functionp nextstr) (funcall nextstr name))
- (t nil))
- (setq ignorep t
- re-list nil)
- (setq re-list (cdr re-list))))
- ;; return the result
- (if ignorep
- (setq ido-ignored-list (cons name ido-ignored-list)))
- ignorep)))))
- ;; Private variable used by `ido-word-matching-substring'.
- (defvar ido-change-word-sub)
- (defun ido-find-common-substring (items subs)
- "Return common string following SUBS in each element of ITEMS."
- (let (res
- alist
- ido-change-word-sub)
- (setq ido-change-word-sub
- (if ido-enable-regexp
- subs
- (regexp-quote subs)))
- (setq res (mapcar #'ido-word-matching-substring items))
- (setq res (delq nil res)) ;; remove any nil elements (shouldn't happen)
- (setq alist (mapcar #'ido-makealist res)) ;; could use an OBARRAY
- ;; try-completion returns t if there is an exact match.
- (let* ((completion-ignore-case ido-case-fold)
- (comp (try-completion subs alist)))
- (if (eq comp t)
- subs
- comp))))
- (defun ido-word-matching-substring (word)
- "Return part of WORD before first match to `ido-change-word-sub'.
- If `ido-change-word-sub' cannot be found in WORD, return nil."
- (let ((case-fold-search ido-case-fold))
- (let ((m (string-match ido-change-word-sub (ido-name word))))
- (if m
- (substring (ido-name word) m)
- ;; else no match
- nil))))
- (defun ido-makealist (res)
- "Return dotted pair (RES . 1)."
- (cons res 1))
- (defun ido-choose-completion-string (choice &rest ignored)
- (when (ido-active)
- ;; Insert the completion into the buffer where completion was requested.
- (and ido-completion-buffer
- (get-buffer ido-completion-buffer)
- (kill-buffer ido-completion-buffer))
- (cond
- ((ido-active t) ;; ido-use-merged-list
- (setq ido-current-directory ""
- ido-text choice
- ido-exit 'done))
- ((not (ido-final-slash choice))
- (setq ido-text choice
- ido-exit 'done))
- (t
- (ido-set-current-directory ido-current-directory choice)
- (setq ido-exit 'refresh)))
- (exit-minibuffer)
- t))
- (defun ido-completion-help ()
- "Show possible completions in a \"*File Completions*\" buffer."
- (interactive)
- (setq ido-rescan nil)
- (let ((temp-buf (and ido-completion-buffer
- (get-buffer ido-completion-buffer)))
- display-it full-list)
- (if (and (eq last-command this-command) temp-buf)
- ;; scroll buffer
- (let (win (buf (current-buffer)))
- (display-buffer temp-buf nil nil)
- (set-buffer temp-buf)
- (setq win (get-buffer-window temp-buf))
- (if (pos-visible-in-window-p (point-max) win)
- (if (or ido-completion-buffer-all-completions
- (boundp 'ido-completion-buffer-full))
- (set-window-start win (point-min))
- (with-no-warnings
- (set (make-local-variable 'ido-completion-buffer-full) t))
- (setq full-list t
- display-it t))
- (scroll-other-window))
- (set-buffer buf))
- (setq display-it t))
- (if (and ido-completion-buffer display-it)
- (with-output-to-temp-buffer ido-completion-buffer
- (let ((completion-list (sort
- (cond
- (ido-directory-too-big
- (message "Reading directory...")
- (setq ido-directory-too-big nil
- ido-ignored-list nil
- ido-cur-list (ido-all-completions)
- ido-rescan t)
- (ido-set-matches)
- (or ido-matches ido-cur-list))
- (ido-use-merged-list
- (ido-flatten-merged-list (or ido-matches ido-cur-list)))
- ((or full-list ido-completion-buffer-all-completions)
- (ido-all-completions))
- (t
- (copy-sequence (or ido-matches ido-cur-list))))
- #'ido-file-lessp)))
- (if (featurep 'xemacs)
- ;; XEmacs extents are put on by default, doesn't seem to be
- ;; any way of switching them off.
- (display-completion-list
- completion-list
- :help-string "ido "
- :activate-callback
- (lambda (&rest _) (message "Doesn't work yet, sorry!")))
- ;; else running Emacs
- ;;(add-hook 'completion-setup-hook 'completion-setup-function)
- (display-completion-list completion-list)))))))
- ;;; KILL CURRENT BUFFER
- (defun ido-kill-buffer-at-head ()
- "Kill the buffer at the head of `ido-matches'.
- If cursor is not at the end of the user input, delete to end of input."
- (interactive)
- (if (not (eobp))
- (delete-region (point) (line-end-position))
- (let ((enable-recursive-minibuffers t)
- (buf (ido-name (car ido-matches)))
- (nextbuf (cadr ido-matches)))
- (cond
- ((get-buffer buf)
- ;; If next match names a buffer use the buffer object; buffer
- ;; name may be changed by packages such as uniquify.
- (when (and nextbuf (get-buffer nextbuf))
- (setq nextbuf (get-buffer nextbuf)))
- (if (null (kill-buffer buf))
- ;; Buffer couldn't be killed.
- (setq ido-rescan t)
- ;; Else `kill-buffer' succeeds so re-make the buffer list
- ;; taking into account packages like uniquify may rename
- ;; buffers.
- (if (bufferp nextbuf)
- (setq nextbuf (buffer-name nextbuf)))
- (setq ido-default-item nextbuf
- ido-text-init ido-text
- ido-exit 'refresh)
- (exit-minibuffer)))
- ;; Handle virtual buffers
- ((assoc buf ido-virtual-buffers)
- (setq recentf-list
- (delete (cdr (assoc buf ido-virtual-buffers)) recentf-list))
- (setq ido-cur-list (delete buf ido-cur-list))
- (setq ido-rescan t))))))
- ;;; BURY CURRENT BUFFER
- (defun ido-bury-buffer-at-head ()
- "Bury the buffer at the head of `ido-matches'."
- (interactive)
- (let ((enable-recursive-minibuffers t)
- (buf (ido-name (car ido-matches)))
- (nextbuf (cadr ido-matches)))
- (when (get-buffer buf)
- (bury-buffer buf)
- (setq ido-default-item nextbuf
- ido-text-init ido-text
- ido-exit 'refresh)
- (exit-minibuffer))))
- ;;; DELETE CURRENT FILE
- (defun ido-delete-file-at-head ()
- "Delete the file at the head of `ido-matches'.
- Trash the file if `delete-by-moving-to-trash' is non-nil.
- If cursor is not at the end of the user input, delete to end of input."
- (interactive)
- (if (not (eobp))
- (delete-region (point) (line-end-position))
- (let ((enable-recursive-minibuffers t)
- (file (ido-name (car ido-matches))))
- (if file
- (setq file (concat ido-current-directory file)))
- (when (and file
- (file-exists-p file)
- (not (file-directory-p file))
- (file-writable-p ido-current-directory)
- (or delete-by-moving-to-trash
- (yes-or-no-p (concat "Delete " file "? "))))
- (delete-file file 'trash)
- ;; Check if file still exists.
- (if (file-exists-p file)
- ;; file could not be deleted
- (setq ido-rescan t)
- ;; else file was killed so remove name from list.
- (setq ido-cur-list (delq (car ido-matches) ido-cur-list)))))))
- ;;; VISIT CHOSEN BUFFER
- (defun ido-visit-buffer (buffer method &optional record)
- "Switch to BUFFER according to METHOD.
- Record command in `command-history' if optional RECORD is non-nil."
- (if (bufferp buffer)
- (setq buffer (buffer-name buffer)))
- (let (win newframe)
- (cond
- ((eq method 'kill)
- (if record
- (ido-record-command 'kill-buffer buffer))
- (kill-buffer buffer))
- ((eq method 'other-window)
- (if record
- (ido-record-command 'switch-to-buffer buffer))
- (switch-to-buffer-other-window buffer))
- ((eq method 'display)
- (display-buffer buffer))
- ((eq method 'other-frame)
- (switch-to-buffer-other-frame buffer)
- (select-frame-set-input-focus (selected-frame)))
- ((eq method 'display-other-frame)
- (display-buffer-other-frame buffer))
- ((and (memq method '(raise-frame maybe-frame))
- window-system
- (setq win (ido-buffer-window-other-frame buffer))
- (or (eq method 'raise-frame)
- (y-or-n-p "Jump to frame? ")))
- (setq newframe (window-frame win))
- (select-frame-set-input-focus newframe)
- (select-window win))
- ;; (eq method 'selected-window)
- (t
- ;; No buffer in other frames...
- (if record
- (ido-record-command 'switch-to-buffer buffer))
- (switch-to-buffer buffer)
- ))))
- (defun ido-buffer-window-other-frame (buffer)
- "Return window pointer if BUFFER is visible in another frame.
- If BUFFER is visible in the current frame, return nil."
- (let ((blist (ido-get-buffers-in-frames 'current)))
- ;;If the buffer is visible in current frame, return nil
- (if (member buffer blist)
- nil
- ;; maybe in other frame or icon
- (get-buffer-window buffer 0) ; better than 'visible
- )))
- ;;; ----------- IDONIZED FUNCTIONS ------------
- ;;;###autoload
- (defun ido-switch-buffer ()
- "Switch to another buffer.
- The buffer is displayed according to `ido-default-buffer-method' -- the
- default is to show it in the same window, unless it is already visible
- in another frame.
- As you type in a string, all of the buffers matching the string are
- displayed if substring-matching is used (default). Look at
- `ido-enable-prefix' and `ido-toggle-prefix'. When you have found the
- buffer you want, it can then be selected. As you type, most keys have
- their normal keybindings, except for the following: \\<ido-buffer-completion-map>
- RET\tSelect the buffer at the front of the list of matches.
- \tIf the list is empty, possibly prompt to create new buffer.
- \\[ido-select-text]\tUse the current input string verbatim.
- \\[ido-next-match]\tPut the first element at the end of the list.
- \\[ido-prev-match]\tPut the last element at the start of the list.
- \\[ido-complete]\tComplete a common suffix to the current string that matches
- \tall buffers. If there is only one match, select that buffer.
- \tIf there is no common suffix, show a list of all matching buffers
- \tin a separate window.
- \\[ido-edit-input]\tEdit input string.
- \\[ido-fallback-command]\tFallback to non-ido version of current command.
- \\[ido-toggle-regexp]\tToggle regexp searching.
- \\[ido-toggle-prefix]\tToggle between substring and prefix matching.
- \\[ido-toggle-case]\tToggle case-sensitive searching of buffer names.
- \\[ido-completion-help]\tShow list of matching buffers in separate window.
- \\[ido-enter-find-file]\tDrop into `ido-find-file'.
- \\[ido-kill-buffer-at-head]\tKill buffer at head of buffer list.
- \\[ido-toggle-ignore]\tToggle ignoring buffers listed in `ido-ignore-buffers'."
- (interactive)
- (ido-buffer-internal ido-default-buffer-method))
- ;;;###autoload
- (defun ido-switch-buffer-other-window ()
- "Switch to another buffer and show it in another window.
- The buffer name is selected interactively by typing a substring.
- For details of keybindings, see `ido-switch-buffer'."
- (interactive)
- (ido-buffer-internal 'other-window 'switch-to-buffer-other-window))
- ;;;###autoload
- (defun ido-display-buffer ()
- "Display a buffer in another window but don't select it.
- The buffer name is selected interactively by typing a substring.
- For details of keybindings, see `ido-switch-buffer'."
- (interactive)
- (ido-buffer-internal 'display 'display-buffer nil nil nil 'ignore))
- ;;;###autoload
- (defun ido-display-buffer-other-frame ()
- "Display a buffer preferably in another frame.
- The buffer name is selected interactively by typing a substring.
- For details of keybindings, see `ido-switch-buffer'."
- (interactive)
- (ido-buffer-internal 'display-other-frame #'display-buffer-other-frame
- nil nil nil #'ignore))
- ;;;###autoload
- (defun ido-kill-buffer ()
- "Kill a buffer.
- The buffer name is selected interactively by typing a substring.
- For details of keybindings, see `ido-switch-buffer'."
- (interactive)
- (ido-buffer-internal 'kill 'kill-buffer "Kill buffer: "
- (buffer-name (current-buffer)) nil 'ignore))
- ;;;###autoload
- (defun ido-insert-buffer ()
- "Insert contents of a buffer in current buffer after point.
- The buffer name is selected interactively by typing a substring.
- For details of keybindings, see `ido-switch-buffer'."
- (interactive)
- (ido-buffer-internal 'insert 'insert-buffer "Insert buffer: "
- nil nil 'ido-enter-insert-file))
- ;;;###autoload
- (defun ido-switch-buffer-other-frame ()
- "Switch to another buffer and show it in another frame.
- The buffer name is selected interactively by typing a substring.
- For details of keybindings, see `ido-switch-buffer'."
- (interactive)
- (if ido-mode
- (ido-buffer-internal 'other-frame)
- (call-interactively 'switch-to-buffer-other-frame)))
- ;;;###autoload
- (defun ido-find-file-in-dir (dir)
- "Switch to another file starting from DIR."
- (interactive "DDir: ")
- (setq dir (file-name-as-directory dir))
- (ido-file-internal ido-default-file-method nil dir nil nil nil 'ignore))
- ;;;###autoload
- (defun ido-find-file ()
- "Edit file with name obtained via minibuffer.
- The file is displayed according to `ido-default-file-method' -- the
- default is to show it in the same window, unless it is already visible
- in another frame.
- The file name is selected interactively by typing a substring. As you
- type in a string, all of the filenames matching the string are displayed
- if substring-matching is used (default). Look at `ido-enable-prefix' and
- `ido-toggle-prefix'. When you have found the filename you want, it can
- then be selected. As you type, most keys have their normal keybindings,
- except for the following: \\<ido-file-completion-map>
- RET\tSelect the file at the front of the list of matches.
- \tIf the list is empty, possibly prompt to create new file.
- \\[ido-select-text]\tUse the current input string verbatim.
- \\[ido-next-match]\tPut the first element at the end of the list.
- \\[ido-prev-match]\tPut the last element at the start of the list.
- \\[ido-complete]\tComplete a common suffix to the current string that matches
- \tall files. If there is only one match, select that file.
- \tIf there is no common suffix, show a list of all matching files
- \tin a separate window.
- \\[ido-magic-delete-char]\tOpen the specified directory in Dired mode.
- \\[ido-edit-input]\tEdit input string (including directory).
- \\[ido-prev-work-directory]\tGo to previous directory in work directory history.
- \\[ido-next-work-directory]\tGo to next directory in work directory history.
- \\[ido-merge-work-directories]\tSearch for file in the work directory history.
- \\[ido-forget-work-directory]\tRemove current directory from the work directory history.
- \\[ido-prev-work-file]\tCycle to previous file in work file history.
- \\[ido-next-work-file]\tCycle to next file in work file history.
- \\[ido-wide-find-file-or-pop-dir]\tPrompt for a file and use find to locate it.
- \\[ido-wide-find-dir-or-delete-dir]\tPrompt for a directory and use find to locate it.
- \\[ido-make-directory]\tPrompt for a directory to create in current directory.
- \\[ido-fallback-command]\tFallback to non-Ido version of current command.
- \\[ido-toggle-regexp]\tToggle regexp searching.
- \\[ido-toggle-prefix]\tToggle between substring and prefix matching.
- \\[ido-toggle-case]\tToggle case-sensitive searching of file names.
- \\[ido-toggle-literal]\tToggle literal reading of this file.
- \\[ido-completion-help]\tShow list of matching files in separate window.
- \\[ido-toggle-ignore]\tToggle ignoring files listed in `ido-ignore-files'."
- (interactive)
- (ido-file-internal ido-default-file-method))
- ;;;###autoload
- (defun ido-find-file-other-window ()
- "Switch to another file and show it in another window.
- The file name is selected interactively by typing a substring.
- For details of keybindings, see `ido-find-file'."
- (interactive)
- (ido-file-internal 'other-window 'find-file-other-window))
- ;;;###autoload
- (defun ido-find-alternate-file ()
- "Switch to another file and show it in another window.
- The file name is selected interactively by typing a substring.
- For details of keybindings, see `ido-find-file'."
- (interactive)
- (ido-file-internal 'alt-file 'find-alternate-file nil "Find alternate file: "))
- ;;;###autoload
- (defun ido-find-alternate-file-other-window ()
- "Find file as a replacement for the file in the next window.
- The file name is selected interactively by typing a substring.
- For details of keybindings, see `ido-find-file'."
- (interactive)
- (ido-file-internal 'alt-file-other-window #'find-alternate-file-other-window))
- ;;;###autoload
- (defun ido-find-file-read-only ()
- "Edit file read-only with name obtained via minibuffer.
- The file name is selected interactively by typing a substring.
- For details of keybindings, see `ido-find-file'."
- (interactive)
- (ido-file-internal 'read-only 'find-file-read-only nil "Find file read-only: "))
- ;;;###autoload
- (defun ido-find-file-read-only-other-window ()
- "Edit file read-only in other window with name obtained via minibuffer.
- The file name is selected interactively by typing a substring.
- For details of keybindings, see `ido-find-file'."
- (interactive)
- (ido-file-internal 'read-only 'find-file-read-only-other-window nil
- "Find file read-only other window: "))
- ;;;###autoload
- (defun ido-find-file-read-only-other-frame ()
- "Edit file read-only in other frame with name obtained via minibuffer.
- The file name is selected interactively by typing a substring.
- For details of keybindings, see `ido-find-file'."
- (interactive)
- (ido-file-internal 'read-only 'find-file-read-only-other-frame nil
- "Find file read-only other frame: "))
- ;;;###autoload
- (defun ido-display-file ()
- "Display a file in another window but don't select it.
- The file name is selected interactively by typing a substring.
- For details of keybindings, see `ido-find-file'."
- (interactive)
- (ido-file-internal 'display nil nil nil nil nil 'ignore))
- ;;;###autoload
- (defun ido-find-file-other-frame ()
- "Switch to another file and show it in another frame.
- The file name is selected interactively by typing a substring.
- For details of keybindings, see `ido-find-file'."
- (interactive)
- (ido-file-internal 'other-frame 'find-file-other-frame))
- ;;;###autoload
- (defun ido-write-file ()
- "Write current buffer to a file.
- The file name is selected interactively by typing a substring.
- For details of keybindings, see `ido-find-file'."
- (interactive)
- (let ((ido-process-ignore-lists t)
- (ido-work-directory-match-only nil)
- (ido-ignore-files (cons "[^/]\\'" ido-ignore-files))
- (ido-report-no-match nil)
- (ido-confirm-unique-completion t)
- (ido-auto-merge-work-directories-length -1))
- (ido-file-internal 'write 'write-file nil "Write file: " nil nil 'ignore)))
- ;;;###autoload
- (defun ido-insert-file ()
- "Insert contents of file in current buffer.
- The file name is selected interactively by typing a substring.
- For details of keybindings, see `ido-find-file'."
- (interactive)
- (ido-file-internal 'insert 'insert-file nil "Insert file: " nil nil 'ido-enter-insert-buffer))
- ;;;###autoload
- (defun ido-dired ()
- "Call `dired' the Ido way.
- The directory is selected interactively by typing a substring.
- For details of keybindings, see `ido-find-file'."
- (interactive)
- (let ((ido-report-no-match nil)
- (ido-auto-merge-work-directories-length -1))
- (ido-file-internal 'dired 'dired nil "Dired: " 'dir)))
- ;;;###autoload
- (defun ido-dired-other-window ()
- "\"Edit\" a directory. Like `ido-dired' but selects in another window.
- The directory is selected interactively by typing a substring.
- For details of keybindings, see `ido-find-file'."
- (interactive)
- (let ((ido-report-no-match nil)
- (ido-auto-merge-work-directories-length -1))
- (ido-file-internal 'dired-other-window #'dired-other-window nil
- "Dired: " 'dir)))
- ;;;###autoload
- (defun ido-dired-other-frame ()
- "\"Edit\" a directory. Like `ido-dired' but makes a new frame.
- The directory is selected interactively by typing a substring.
- For details of keybindings, see `ido-find-file'."
- (interactive)
- (let ((ido-report-no-match nil)
- (ido-auto-merge-work-directories-length -1))
- (ido-file-internal 'dired-other-frame #'dired-other-frame nil
- "Dired: " 'dir)))
- (defun ido-list-directory ()
- "Call `list-directory' the Ido way.
- The directory is selected interactively by typing a substring.
- For details of keybindings, see `ido-find-file'."
- (interactive)
- (let ((ido-report-no-match nil)
- (ido-auto-merge-work-directories-length -1))
- (ido-file-internal 'list-directory 'list-directory nil "List directory: " 'dir)))
- ;;; XEmacs hack for showing default buffer
- ;; The first time we enter the minibuffer, Emacs puts up the default
- ;; buffer to switch to, but XEmacs doesn't -- presumably there is a
- ;; subtle difference in the two versions of post-command-hook. The
- ;; default is shown for both whenever we delete all of our text
- ;; though, indicating its just a problem the first time we enter the
- ;; function. To solve this, we use another entry hook for emacs to
- ;; show the default the first time we enter the minibuffer.
- ;;; ICOMPLETE TYPE CODE
- (defun ido-initiate-auto-merge (buffer)
- (ido-trace "\n*merge timeout*" buffer)
- (setq ido-auto-merge-timer nil)
- (when (and (buffer-live-p buffer)
- (ido-active)
- (boundp 'ido-eoinput) ido-eoinput)
- (let ((contents (buffer-substring-no-properties (minibuffer-prompt-end) ido-eoinput)))
- (ido-trace "request merge")
- (setq ido-use-merged-list 'auto
- ido-text-init contents
- ido-rotate-temp t
- ido-exit 'refresh)
- (with-current-buffer buffer
- (ido-tidy))
- (throw 'ido contents))))
- (defun ido-exhibit ()
- "Post command hook for Ido."
- ;; Find matching files and display a list in the minibuffer.
- ;; Copied from `icomplete-exhibit' with two changes:
- ;; 1. It prints a default file name when there is no text yet entered.
- ;; 2. It calls my completion routine rather than the standard completion.
- (when (ido-active)
- (let ((contents (buffer-substring-no-properties (minibuffer-prompt-end) (point-max)))
- (buffer-undo-list t)
- try-single-dir-match
- refresh)
- (when ido-trace-enable
- (ido-trace "\nexhibit" this-command)
- (ido-trace "dir" ido-current-directory)
- (ido-trace "contents" contents)
- (ido-trace "list" ido-cur-list)
- (ido-trace "matches" ido-matches)
- (ido-trace "rescan" ido-rescan))
- (save-excursion
- (goto-char (point-max))
- ;; Register the end of input, so we know where the extra stuff (match-status info) begins:
- (unless (boundp 'ido-eoinput)
- ;; In case it got wiped out by major mode business:
- (make-local-variable 'ido-eoinput))
- (setq ido-eoinput (point))
- ;; Handle explicit directory changes
- (cond
- ((memq ido-cur-item '(buffer list))
- )
- ((= (length contents) 0)
- )
- ((= (length contents) 1)
- (cond
- ((and (ido-is-tramp-root) (string-equal contents "/"))
- (ido-set-current-directory ido-current-directory contents)
- (setq refresh t))
- ((and (ido-unc-hosts) (string-equal contents "/")
- (let ((ido-enable-tramp-completion nil))
- (ido-is-root-directory)))
- (ido-set-current-directory "//")
- (setq refresh t))
- ))
- ((and (string-match (if ido-enable-tramp-completion ".[:@]\\'" ".:\\'") contents)
- (ido-is-root-directory) ;; Ange-ftp or tramp
- (not (ido-local-file-exists-p contents)))
- (ido-set-current-directory ido-current-directory contents)
- (when (ido-is-slow-ftp-host)
- (setq ido-exit 'fallback)
- (exit-minibuffer))
- (setq refresh t))
- ((ido-final-slash contents) ;; xxx/
- (ido-trace "final slash" contents)
- (cond
- ((string-equal contents "~/")
- (ido-set-current-home)
- (setq refresh t))
- ((string-equal contents "../")
- (ido-up-directory t)
- (setq refresh t))
- ((string-equal contents "./")
- (setq refresh t))
- ((string-match "\\`~[-_a-zA-Z0-9]+[$]?/\\'" contents)
- (ido-trace "new home" contents)
- (ido-set-current-home contents)
- (setq refresh t))
- ((string-match "[$][A-Za-z0-9_]+/\\'" contents)
- (let ((exp (condition-case ()
- (expand-file-name
- (substitute-in-file-name (substring contents 0 -1))
- ido-current-directory)
- (error nil))))
- (ido-trace contents exp)
- (when (and exp (file-directory-p exp))
- (ido-set-current-directory (file-name-directory exp))
- (setq ido-text-init (file-name-nondirectory exp))
- (setq refresh t))))
- ((and (memq system-type '(windows-nt ms-dos))
- (string-equal (substring contents 1) ":/"))
- (ido-set-current-directory (file-name-directory contents))
- (setq refresh t))
- ((string-equal (substring contents -2 -1) "/")
- (ido-set-current-directory
- (if (memq system-type '(windows-nt ms-dos))
- (expand-file-name "/" ido-current-directory)
- "/"))
- (setq refresh t))
- ((and (or ido-directory-nonreadable ido-directory-too-big)
- (file-directory-p (concat ido-current-directory (file-name-directory contents))))
- (ido-set-current-directory
- (concat ido-current-directory (file-name-directory contents)))
- (setq refresh t))
- (t
- (ido-trace "try single dir")
- (setq try-single-dir-match t))))
- ((and (string-equal (substring contents -2 -1) "/")
- (not (string-match "[$]" contents)))
- (ido-set-current-directory
- (cond
- ((= (length contents) 2)
- "/")
- (ido-matches
- (concat ido-current-directory (ido-name (car ido-matches))))
- (t
- (concat ido-current-directory (substring contents 0 -1)))))
- (setq ido-text-init (substring contents -1))
- (setq refresh t))
- ((and (not ido-use-merged-list)
- (not (ido-final-slash contents))
- (eq ido-try-merged-list t)
- (numberp ido-auto-merge-work-directories-length)
- (> ido-auto-merge-work-directories-length 0)
- (= (length contents) ido-auto-merge-work-directories-length)
- (not (and ido-auto-merge-inhibit-characters-regexp
- (string-match ido-auto-merge-inhibit-characters-regexp contents)))
- (not (input-pending-p)))
- (setq ido-use-merged-list 'auto
- ido-text-init contents
- ido-rotate-temp t)
- (setq refresh t))
- (t nil))
- (when refresh
- (ido-trace "refresh on /" ido-text-init)
- (setq ido-exit 'refresh)
- (exit-minibuffer))
- (when (and ido-enter-matching-directory
- ido-matches
- (or (eq ido-enter-matching-directory 'first)
- (null (cdr ido-matches)))
- (ido-final-slash (ido-name (car ido-matches)))
- (or try-single-dir-match
- (eq ido-enter-matching-directory t)))
- (ido-trace "single match" (car ido-matches))
- (ido-set-current-directory
- (concat ido-current-directory (ido-name (car ido-matches))))
- (setq ido-exit 'refresh)
- (exit-minibuffer))
- ;; Update the list of matches
- (setq ido-text contents)
- (ido-set-matches)
- (ido-trace "new " ido-matches)
- (when (and (boundp 'ido-enable-virtual-buffers)
- (not (eq ido-enable-virtual-buffers 'always))
- (eq ido-cur-item 'buffer)
- (eq ido-use-virtual-buffers 'auto))
- (when (and (not ido-enable-virtual-buffers)
- (not ido-matches))
- (setq ido-text-init ido-text)
- (setq ido-enable-virtual-buffers t)
- (setq ido-exit 'refresh)
- (exit-minibuffer))
- ;; If input matches real buffers turn off virtual buffers.
- (when (and ido-enable-virtual-buffers
- ido-matches
- (ido-set-matches-1 (ido-make-buffer-list-1)))
- (setq ido-enable-virtual-buffers nil)
- (setq ido-text-init ido-text)
- (setq ido-exit 'refresh)
- (exit-minibuffer)))
- (when (and (not ido-matches)
- (not ido-directory-nonreadable)
- (not ido-directory-too-big)
- ;; ido-rescan ?
- ido-process-ignore-lists
- ido-ignored-list)
- (let ((ido-process-ignore-lists nil)
- (ido-rotate ido-rotate)
- (ido-cur-list ido-ignored-list))
- (ido-trace "try all" ido-ignored-list)
- (ido-set-matches))
- (when ido-matches
- (ido-trace "found " ido-matches)
- (setq ido-rescan t)
- (setq ido-process-ignore-lists-inhibit t)
- (setq ido-text-init ido-text)
- (setq ido-exit 'refresh)
- (exit-minibuffer)))
- (when (and
- ido-rescan
- (not ido-matches)
- (memq ido-cur-item '(file dir))
- (not (ido-is-root-directory))
- (> (length contents) 1)
- (not (string-match "[$]" contents))
- (not ido-directory-nonreadable)
- (not ido-directory-too-big))
- (ido-trace "merge?")
- (if ido-use-merged-list
- (ido-undo-merge-work-directory contents nil)
- (when (and (eq ido-try-merged-list t)
- (numberp ido-auto-merge-work-directories-length)
- (= ido-auto-merge-work-directories-length 0)
- (not (and ido-auto-merge-inhibit-characters-regexp
- (string-match ido-auto-merge-inhibit-characters-regexp contents)))
- (not (input-pending-p)))
- (ido-trace "\n*start timer*")
- (setq ido-auto-merge-timer
- (run-with-timer ido-auto-merge-delay-time nil 'ido-initiate-auto-merge (current-buffer))))))
- (setq ido-rescan t)
- (if (and ido-use-merged-list
- ido-matches
- (not (string-equal (car (cdr (car ido-matches))) ido-current-directory)))
- (progn
- (ido-set-current-directory (car (cdr (car ido-matches))))
- (setq ido-use-merged-list t
- ido-exit 'keep
- ido-text-init ido-text)
- (exit-minibuffer)))
- ;; Insert the match-status information:
- (ido-set-common-completion)
- (let ((inf (ido-completions contents)))
- (setq ido-show-confirm-message nil)
- (ido-trace "inf" inf)
- (insert inf))
- ))))
- (defun ido-completions (name)
- "Return the string that is displayed after the user's text.
- Modified from `icomplete-completions'."
- (let* ((comps ido-matches)
- (ind (and (consp (car comps)) (> (length (cdr (car comps))) 1)
- ido-merged-indicator))
- first)
- (if (and ind ido-use-faces)
- (put-text-property 0 1 'face 'ido-indicator ind))
- (if (and ido-use-faces comps)
- (let* ((fn (ido-name (car comps)))
- (ln (length fn)))
- (setq first (format "%s" fn))
- (put-text-property 0 ln 'face
- (if (= (length comps) 1)
- (if ido-incomplete-regexp
- 'ido-incomplete-regexp
- 'ido-only-match)
- 'ido-first-match)
- first)
- (if ind (setq first (concat first ind)))
- (setq comps (cons first (cdr comps)))))
- (cond ((null comps)
- (cond
- (ido-show-confirm-message
- (or (nth 10 ido-decorations) " [Confirm]"))
- (ido-directory-nonreadable
- (or (nth 8 ido-decorations) " [Not readable]"))
- (ido-directory-too-big
- (or (nth 9 ido-decorations) " [Too big]"))
- (ido-report-no-match
- (nth 6 ido-decorations)) ;; [No match]
- (t "")))
- (ido-incomplete-regexp
- (concat " " (car comps)))
- ((null (cdr comps)) ;one match
- (concat (if (if (not ido-enable-regexp)
- (= (length (ido-name (car comps))) (length name))
- ;; We can't rely on the length of the input
- ;; for regexps, so explicitly check for a
- ;; complete match
- (string-match name (ido-name (car comps)))
- (string-equal (match-string 0 (ido-name (car comps)))
- (ido-name (car comps))))
- ""
- ;; When there is only one match, show the matching file
- ;; name in full, wrapped in [ ... ].
- (concat
- (or (nth 11 ido-decorations) (nth 4 ido-decorations))
- (ido-name (car comps))
- (or (nth 12 ido-decorations) (nth 5 ido-decorations))))
- (if (not ido-use-faces) (nth 7 ido-decorations)))) ;; [Matched]
- (t ;multiple matches
- (let* ((items (if (> ido-max-prospects 0) (1+ ido-max-prospects) 999))
- (alternatives
- (apply
- #'concat
- (cdr (apply
- #'nconc
- (mapcar
- (lambda (com)
- (setq com (ido-name com))
- (setq items (1- items))
- (cond
- ((< items 0) ())
- ((= items 0) (list (nth 3 ido-decorations))) ; " | ..."
- (t
- (list (or ido-separator (nth 2 ido-decorations)) ; " | "
- (let ((str (substring com 0)))
- (if (and ido-use-faces
- (not (string= str first))
- (ido-final-slash str))
- (put-text-property 0 (length str) 'face 'ido-subdir str))
- str)))))
- comps))))))
- (concat
- ;; put in common completion item -- what you get by pressing tab
- (if (and (stringp ido-common-match-string)
- (> (length ido-common-match-string) (length name)))
- (concat (nth 4 ido-decorations) ;; [ ... ]
- (substring ido-common-match-string (length name))
- (nth 5 ido-decorations)))
- ;; list all alternatives
- (nth 0 ido-decorations) ;; { ... }
- alternatives
- (nth 1 ido-decorations)))))))
- (defun ido-minibuffer-setup ()
- "Minibuffer setup hook for Ido."
- ;; Copied from `icomplete-minibuffer-setup-hook'.
- (when (ido-active)
- (add-hook 'pre-command-hook 'ido-tidy nil t)
- (add-hook 'post-command-hook 'ido-exhibit nil t)
- (when (featurep 'xemacs)
- (ido-exhibit)
- (goto-char (point-min)))
- (run-hooks 'ido-minibuffer-setup-hook)
- (when ido-initial-position
- (goto-char (+ (minibuffer-prompt-end) ido-initial-position))
- (setq ido-initial-position nil))))
- (defun ido-tidy ()
- "Pre command hook for Ido."
- ;; Remove completions display, if any, prior to new user input.
- ;; Copied from `icomplete-tidy'."
- (when ido-auto-merge-timer
- (ido-trace "\n*cancel timer*" this-command)
- (cancel-timer ido-auto-merge-timer)
- (setq ido-auto-merge-timer nil))
- (when (ido-active)
- (if (bound-and-true-p ido-eoinput)
- (if (> ido-eoinput (point-max))
- ;; Oops, got rug pulled out from under us - reinit:
- (setq ido-eoinput (point-max))
- (let ((inhibit-read-only t)
- (buffer-undo-list t))
- (delete-region ido-eoinput (point-max))))
- ;; Reestablish the local variable 'cause minibuffer-setup is weird:
- (make-local-variable 'ido-eoinput)
- (setq ido-eoinput 1))))
- (defun ido-summary-buffers-to-end ()
- ;; Move the summaries to the end of the buffer list.
- ;; This is an example function which can be hooked on to
- ;; `ido-make-buffer-list-hook'. Any buffer matching the regexps
- ;; `Summary' or `output\*$'are put to the end of the list.
- (let ((summaries (delq nil (mapcar
- (lambda (x)
- (if (or
- (string-match "Summary" x)
- (string-match "output\\*\\'" x))
- x))
- ido-temp-list))))
- (ido-to-end summaries)))
- ;;; Helper functions for other programs
- (put 'ibuffer-find-file 'ido 'find-file)
- (put 'dired 'ido 'dir)
- (put 'dired-other-window 'ido 'dir)
- (put 'dired-other-frame 'ido 'dir)
- ;; See http://debbugs.gnu.org/11954 for reasons.
- (put 'dired-do-copy 'ido 'ignore)
- (put 'dired-do-rename 'ido 'ignore)
- ;;;###autoload
- (defun ido-read-buffer (prompt &optional default require-match predicate)
- "Ido replacement for the built-in `read-buffer'.
- Return the name of a buffer selected.
- PROMPT is the prompt to give to the user. DEFAULT if given is the default
- buffer to be selected, which will go to the front of the list.
- If REQUIRE-MATCH is non-nil, an existing buffer must be selected."
- (let* ((ido-current-directory nil)
- (ido-directory-nonreadable nil)
- (ido-directory-too-big nil)
- (ido-context-switch-command 'ignore)
- (buf (ido-read-internal 'buffer prompt 'ido-buffer-history default require-match)))
- (if (eq ido-exit 'fallback)
- (let ((read-buffer-function nil))
- (run-hook-with-args 'ido-before-fallback-functions 'read-buffer)
- (read-buffer prompt default require-match predicate))
- buf)))
- ;;;###autoload
- (defun ido-read-file-name (prompt &optional dir default-filename mustmatch initial predicate)
- "Ido replacement for the built-in `read-file-name'.
- Read file name, prompting with PROMPT and completing in directory DIR.
- See `read-file-name' for additional parameters."
- (let (filename)
- (cond
- ((or (eq predicate 'file-directory-p)
- (eq (and (symbolp this-command)
- (get this-command 'ido)) 'dir)
- (memq this-command ido-read-file-name-as-directory-commands))
- (setq filename
- (ido-read-directory-name prompt dir default-filename mustmatch initial)))
- ((and (not (eq (and (symbolp this-command)
- (get this-command 'ido)) 'ignore))
- (not (memq this-command ido-read-file-name-non-ido))
- (or (null predicate) (eq predicate 'file-exists-p)))
- (let* (ido-saved-vc-hb
- (ido-context-switch-command
- (if (eq (and (symbolp this-command)
- (get this-command 'ido)) 'find-file)
- nil 'ignore))
- (vc-handled-backends (and (boundp 'vc-handled-backends) vc-handled-backends))
- (minibuffer-completing-file-name t)
- (ido-current-directory (ido-expand-directory dir))
- (ido-directory-nonreadable (not (file-readable-p ido-current-directory)))
- (ido-directory-too-big (and (not ido-directory-nonreadable)
- (ido-directory-too-big-p ido-current-directory)))
- (ido-work-directory-index -1)
- (ido-show-dot-for-dired (and ido-show-dot-for-dired
- (not default-filename)))
- (ido-work-file-index -1)
- (ido-find-literal nil))
- (setq ido-exit nil)
- (setq filename
- (ido-read-internal 'file prompt 'ido-file-history
- (cond ; Bug#11861.
- ((stringp default-filename) default-filename)
- ((consp default-filename) (car default-filename))
- ((and (not default-filename) initial)
- (expand-file-name initial dir))
- (buffer-file-name buffer-file-name))
- mustmatch initial))
- (setq dir ido-current-directory) ; See bug#1516.
- (cond
- ((eq ido-exit 'fallback)
- (setq filename 'fallback))
- ((eq ido-exit 'dired)
- (setq filename ido-current-directory))
- (filename
- (setq filename
- (concat ido-current-directory filename))))))
- (t
- (setq filename 'fallback)))
- (if (eq filename 'fallback)
- (let ((read-file-name-function nil))
- (run-hook-with-args 'ido-before-fallback-functions 'read-file-name)
- (read-file-name prompt dir default-filename mustmatch initial predicate))
- filename)))
- ;;;###autoload
- (defun ido-read-directory-name (prompt &optional dir default-dirname mustmatch initial)
- "Ido replacement for the built-in `read-directory-name'.
- Read directory name, prompting with PROMPT and completing in directory DIR.
- See `read-directory-name' for additional parameters."
- (let* (filename
- (minibuffer-completing-file-name t)
- (ido-context-switch-command 'ignore)
- ido-saved-vc-hb
- (ido-current-directory (ido-expand-directory dir))
- (ido-directory-nonreadable (not (file-readable-p ido-current-directory)))
- (ido-directory-too-big (and (not ido-directory-nonreadable)
- (ido-directory-too-big-p ido-current-directory)))
- (ido-work-directory-index -1)
- (ido-work-file-index -1))
- (setq filename (ido-read-internal
- 'dir prompt 'ido-file-history
- (or default-dirname ; Bug#11861.
- (if initial
- (expand-file-name initial ido-current-directory)
- ido-current-directory))
- mustmatch initial))
- (cond
- ((eq ido-exit 'fallback)
- (let ((read-file-name-function nil))
- (run-hook-with-args 'ido-before-fallback-functions 'read-directory-name)
- (read-directory-name prompt ido-current-directory
- default-dirname mustmatch initial)))
- ((equal filename ".") ido-current-directory)
- (t (concat ido-current-directory filename)))))
- ;;;###autoload
- (defun ido-completing-read (prompt choices &optional _predicate require-match
- initial-input hist def _inherit-input-method)
- "Ido replacement for the built-in `completing-read'.
- Read a string in the minibuffer with Ido-style completion.
- PROMPT is a string to prompt with; normally it ends in a colon and a space.
- CHOICES is a list of strings which are the possible completions.
- PREDICATE and INHERIT-INPUT-METHOD are currently ignored; they are included
- to be compatible with `completing-read'.
- If REQUIRE-MATCH is non-nil, the user is not allowed to exit unless
- the input is (or completes to) an element of CHOICES or is null.
- If the input is null, `ido-completing-read' returns DEF, or an empty
- string if DEF is nil, regardless of the value of REQUIRE-MATCH.
- If INITIAL-INPUT is non-nil, insert it in the minibuffer initially,
- with point positioned at the end.
- HIST, if non-nil, specifies a history list.
- DEF, if non-nil, is the default value."
- (let ((ido-current-directory nil)
- (ido-directory-nonreadable nil)
- (ido-directory-too-big nil)
- (ido-context-switch-command 'ignore)
- (ido-choice-list choices))
- ;; Initialize ido before invoking ido-read-internal
- (ido-common-initialization)
- (ido-read-internal 'list prompt hist def require-match initial-input)))
- (defun ido-unload-function ()
- "Unload the Ido library."
- (ido-mode -1)
- (setq minor-mode-map-alist (assq-delete-all 'ido-mode minor-mode-map-alist))
- ;; continue standard unloading
- nil)
- (provide 'ido)
- ;;; ido.el ends here
|