Minor fixes to a recent contribution to ido.el
[bpt/emacs.git] / lisp / ido.el
CommitLineData
789d1bf0
KS
1;;; ido.el --- interactively do things with buffers and files.
2
0d30b337 3;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
114f9c96 4;; 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
789d1bf0
KS
5
6;; Author: Kim F. Storm <storm@cua.dk>
7;; Based on: iswitchb by Stephen Eglen <stephen@cns.ed.ac.uk>
8;; Keywords: extensions convenience
9
10;; This file is part of GNU Emacs.
11
eb3fa2cf 12;; GNU Emacs is free software: you can redistribute it and/or modify
789d1bf0 13;; it under the terms of the GNU General Public License as published by
eb3fa2cf
GM
14;; the Free Software Foundation, either version 3 of the License, or
15;; (at your option) any later version.
789d1bf0
KS
16
17;; GNU Emacs is distributed in the hope that it will be useful,
18;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20;; GNU General Public License for more details.
21
22;; You should have received a copy of the GNU General Public License
eb3fa2cf 23;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
789d1bf0 24
789d1bf0
KS
25
26;;; Commentary:
27
28;; Ido - interactive do - switches between buffers and opens files and
29;; directories with a minimum of keystrokes. It is a superset of
30;; iswitchb, the interactive buffer switching package by Stephen Eglen.
31
32;; Interactive substring matching
33;; ------------------------------
34;;
35;; As you type in a substring, the list of buffers or files currently
36;; matching the substring are displayed as you type. The list is
37;; ordered so that the most recent buffers or files visited come at
38;; the start of the list.
39;;
40;; The buffer or file at the start of the list will be the one visited
41;; when you press RETURN. By typing more of the substring, the list is
42;; narrowed down so that gradually the buffer or file you want will be
43;; at the top of the list. Alternatively, you can use C-s and C-r (or
44;; the right and left arrow keys) to rotate buffer or file names in the
45;; list until the one you want is at the top of the list.
46;;
47;; Completion is also available so that you can see what is common to
48;; all of the matching buffers or files as you type.
49;;
50;; Example:
51;;
52;; If I have two buffers called "123456" and "123", with "123456" the
53;; most recent, when I use ido-switch-buffer, I first of all get
54;; presented with the list of all the buffers
55;;
04c95147 56;; Buffer: {123456 | 123}
789d1bf0
KS
57;;
58;; If I then press 2:
04c95147 59;; Buffer: 2[3]{123456 | 123}
789d1bf0
KS
60;;
61;; The list in {...} are the matching buffers, most recent first
62;; (buffers visible in the current frame are put at the end of the
63;; list by default). At any time I can select the item at the head of
f2801d2a
KS
64;; the list by pressing RET. I can also put the first element at the
65;; end of the list by pressing C-s or [right], or bring the last
66;; element to the head of the list by pressing C-r or [left].
789d1bf0
KS
67;;
68;; The item in [...] indicates what can be added to my input by
69;; pressing TAB. In this case, I will get "3" added to my input.
70
71;; So, I press TAB:
04c95147 72;; Buffer: 23{123456 | 123}
789d1bf0
KS
73;;
74;; At this point, I still have two matching buffers.
75;; If I want the first buffer in the list, I simply press RET. If I
76;; wanted the second in the list, I could press C-s to move it to the
77;; top of the list and then RET to select it.
78;;
79;; However, if I type 4, I only have one match left:
04c95147
KS
80;; Buffer: 234[123456]
81;;
82;; Since there is only one matching buffer left, it is given in [] and
83;; it is shown in the `ido-only-match' face (ForestGreen). I can now
84;; press TAB or RET to go to that buffer.
789d1bf0 85;;
04c95147
KS
86;; If I want to create a new buffer named "234", I press C-j instead of
87;; TAB or RET.
789d1bf0 88;;
04c95147 89;; If instead, I type "a":
789d1bf0
KS
90;; Buffer: 234a [No match]
91;; There are no matching buffers. If I press RET or TAB, I can be
92;; prompted to create a new buffer called "234a".
93;;
94;; Of course, where this function comes in really useful is when you
95;; can specify the buffer using only a few keystrokes. In the above
96;; example, the quickest way to get to the "123456" file would be
97;; just to type 4 and then RET (assuming there isn't any newer buffer
98;; with 4 in its name).
99
100;; Likewise, if you use C-x C-f (ido-find-file), the list of files and
101;; directories in the current directory is provided in the same
102;; fashion as the buffers above. The files and directories are
103;; normally sorted in alphabetical order, but the most recently
104;; visited directory is placed first to speed up navigating to
105;; directories that you have visited recently.
106;;
107;; In addition to scrolling through the list using [right] and [left],
108;; you can use [up] and [down] to quickly scroll the list to the next
109;; or previous subdirectory.
110;;
111;; To go down into a subdirectory, and continue the file selection on
112;; the files in that directory, simply move the directory to the head
113;; of the list and hit RET.
114;;
115;; To go up to the parent directory, delete any partial file name
116;; already specified (e.g. using [backspace]) and hit [backspace].
117;;
118;; To go to the root directory (on the current drive), enter two
119;; slashes. On MS-DOS or Windows, to select the root of another
120;; drive, enter X:/ where X is the drive letter. You can also visit
121;; files on other hosts using the ange-ftp notations `/host:' and
122;; `/user@host:'. See the variable `ido-slow-ftp-hosts' if you want
71296446 123;; to inhibit the ido substring matching for ftp access.
789d1bf0
KS
124;;
125;; If for some reason you cannot specify the proper file using
126;; ido-find-file, you can press C-f to enter the normal find-file.
127;; You can also press C-b to drop into ido-switch-buffer.
128
129;; See the doc string of ido-switch-buffer and ido-find-file for full
130;; keybindings and features.
131;; (describe-function 'ido-find-file)
132
133;; Hidden buffers and files
134;; ------------------------
135;;
136;; Normally, ido does not include hidden buffers (whose name starts
137;; with a space) and hidden files and directories (whose name starts
138;; with `.') in the list of possible completions. However, if the
139;; substring you enter does not match any of the visible buffers or
140;; files, ido will automatically look for completions among the hidden
141;; buffers or files.
142;;
143;; You can toggle display of the hidden buffers and files with C-a.
144
145;; Additional functionality
146;; ------------------------
147;;
148;; After C-x b, the buffer at the head of the list can be killed by
149;; pressing C-k. If the buffer needs saving, you will be queried
150;; before the buffer is killed.
151;;
152;; Likewise, after C-x C-f, you can delete (i.e. physically remove)
153;; the file at the head of the list with C-k. You will always be
154;; asked for confirmation before the file is deleted.
155;;
156;; If you enter C-x b to switch to a buffer visiting a given file, and
157;; you find that the file you are after is not in any buffer, you can
158;; press C-f to immediately drop into ido-find-file. And you can
159;; switch back to buffer selection with C-b.
160
161;; Prefix matching
162;; ---------------
163;;
164;; The standard way of completion with Unix-shells and Emacs is to insert a
165;; PREFIX and then hitting TAB (or another completion key). Cause of this
166;; behavior has become second nature to a lot of emacs users `ido' offers in
167;; addition to the default substring-matching-method (look above) also the
168;; prefix-matching-method. The kind of matching is the only difference to
169;; the description of the substring-matching above.
170;;
171;; You can toggle prefix matching with C-p.
172;;
173;; Example:
174;;
175;; If you have again two Buffers "123456" and "123" then hitting "2" does
f2801d2a 176;; not match because "2" is not a PREFIX in any of the buffer-names.
789d1bf0
KS
177
178;; Flexible matching
179;; -----------------
180;;
181;; If you set ido-enable-flex-matching, ido will do a more flexible
182;; matching (unless regexp matching is active) to find possible matches
183;; among the available buffer or file names if no matches are found using
184;; the normal prefix or substring matching.
185;;
186;; The flexible matching implies that any item which simply contains all
187;; of the entered characters in the specified sequence will match.
188;;
189;; Example:
190;;
191;; If you have four files "alpha", "beta", "gamma", and "delta",
192;; entering "aa" will match "alpha" and "gamma", while "ea" matches
193;; "beta" and "delta". If prefix matching is also active, "aa" only
194;; matches "alpha", while "ea" does not match any files.
195
196;; Regexp matching
197;; ---------------
198;;
199;; There is limited provision for regexp matching within ido,
200;; enabled through `ido-enable-regexp' (toggle with C-t).
f2801d2a
KS
201;; This allows you to type `[ch]$' for example and see all file names
202;; ending in `c' or `h'.
203;;
204;; Note: ido-style completion is inhibited when you enable regexp matching.
789d1bf0
KS
205
206
207;; Customization
208;; -------------
209;;
210;; Customize the `ido' group to change the `ido' functionality.
211;;
3729cc87
KS
212;; To modify the keybindings, use the ido-setup-hook. For example:
213;;(add-hook 'ido-setup-hook 'ido-my-keys)
789d1bf0
KS
214;;
215;;(defun ido-my-keys ()
216;; "Add my keybindings for ido."
facf67fd 217;; (define-key ido-completion-map " " 'ido-next-match)
789d1bf0
KS
218;; )
219
220;; Seeing all the matching buffers or files
221;; ----------------------------------------
222;;
223;; If you have many matching files, they may not all fit onto one
224;; line of the minibuffer. Normally, the minibuffer window will grow
225;; to show you more of the matching files (depending on the setting
226;; of the variables `resize-mini-windows' and `max-mini-window-height').
227;; If you want ido to behave differently from the default minibuffer
fffa137c 228;; resizing behavior, set the variable `ido-max-window-height'.
789d1bf0
KS
229;;
230;; Also, to improve the responsiveness of ido, the maximum number of
231;; matching items is limited to 12, but you can increase or removed
232;; this limit via the `ido-max-prospects' variable.
233
234;; To see a full list of all matching buffers in a separate buffer,
235;; hit ? or press TAB when there are no further completions to the
236;; substring. Repeated TAB presses will scroll you through this
237;; separate buffer.
238
239;; Changing the list of files
240;; --------------------------
241
242;; By default, the list of current files is most recent first,
243;; oldest last, with the exception that the files visible in the
244;; current frame are put at the end of the list. A hook exists to
245;; allow other functions to order the list. For example, if you add:
246;;
247;; (add-hook 'ido-make-buffer-list-hook 'ido-summary-buffers-to-end)
248;;
249;; then all files matching "Summary" are moved to the end of the
250;; list. (I find this handy for keeping the INBOX Summary and so on
251;; out of the way.) It also moves files matching "output\*$" to the
90a02640 252;; end of the list (these are created by AUCTeX when compiling.)
789d1bf0
KS
253;; Other functions could be made available which alter the list of
254;; matching files (either deleting or rearranging elements.)
255
256;; Highlighting
257;; ------------
258
259;; The highlighting of matching items is controlled via ido-use-faces.
ccba8bb6
KS
260;; The faces used are ido-first-match, ido-only-match and
261;; ido-subdir.
789d1bf0
KS
262;; Colouring of the matching item was suggested by
263;; Carsten Dominik (dominik@strw.leidenuniv.nl).
264
265;; Replacement for read-buffer and read-file-name
266;; ----------------------------------------------
267
268;; ido-read-buffer and ido-read-file-name have been written to be drop
269;; in replacements for the normal buffer and file name reading
270;; functions `read-buffer' and `read-file-name'.
271
272;; To use ido for all buffer and file selections in Emacs, customize the
273;; variable `ido-everywhere'.
274
fffa137c 275;; Using ido-like behavior in other lisp packages
789d1bf0
KS
276;; -----------------------------------------------
277
278;; If you don't want to rely on the `ido-everywhere' functionality,
279;; ido-read-buffer, ido-read-file-name, and ido-read-directory-name
280;; can be used by other packages to read a buffer name, a file name,
281;; or a directory name in the `ido' way.
282
04c95147
KS
283;;; Acknowledgements
284
285;; Infinite amounts of gratitude goes to Stephen Eglen <stephen@cns.ed.ac.uk>
286;; who wrote iswitch-buffer mode - from which I ripped off 99% of the code
287;; for ido-switch-buffer and found the inspiration for ido-find-file.
288;; The ido package would never have existed without his work.
289
290;; Also thanks to Klaus Berndl, Rohit Namjoshi, Robert Fenk, Alex
291;; Schroeder, Bill Benedetto, Stephen Eglen, and many others for bug
292;; fixes and improvements.
293
294;;; History
295
296;; Since I discovered Stephen Eglen's excellent iswitchb package, I just
297;; couldn't live without it, but once being addicted to switching buffers
298;; with a minimum of keystrokes, I soon found that opening files in the
299;; old-fashioned way was just too slow - so I decided to write a package
300;; which could open files with the same speed and ease as iswitchb could
301;; switch buffers.
302
303;; I originally wrote a separate ifindf.el package based on a copy of
304;; iswitchb.el, which did for opening files what iswitchb did for
305;; switching buffers. Along the way, I corrected a few errors in
306;; ifindf which could have found its way back into iswitchb, but since
307;; most of the functionality of the two package was practically
308;; identical, I decided that the proper thing to do was to merge my
309;; ifindf package back into iswitchb.
310;;
311;; This is basically what ido (interactively do) is all about; but I
312;; found it ackward to merge my changes into the "iswitchb-" namespace,
313;; so I invented a common "ido-" namespace for the merged packages.
314;;
315;; This version is based on ido.el version 1.57 released on
316;; gnu.emacs.sources adapted for emacs 22.1 to use command remapping
317;; and optionally hooking the read-buffer and read-file-name functions.
318;;
319;; Prefix matching was added by Klaus Berndl <klaus.berndl@sdm.de> based on
320;; an idea of Yuji Minejima <ggb01164@nifty.ne.jp> and his mcomplete-package.
321
789d1bf0
KS
322
323;;; Code:
324
b2ddf2d2 325(defvar cua-inhibit-cua-keys)
9caf8a8f 326(defvar recentf-list)
b2ddf2d2 327
789d1bf0
KS
328;;; User Variables
329;;
330;; These are some things you might want to change.
331
332(defun ido-fractionp (n)
333 (and (numberp n) (> n 0.0) (<= n 1.0)))
334
335(defgroup ido nil
336 "Switch between files using substrings."
337 :group 'extensions
338 :group 'convenience
bf247b6e 339 :version "22.1"
789d1bf0
KS
340 :link '(emacs-commentary-link :tag "Commentary" "ido.el")
341 :link '(emacs-library-link :tag "Lisp File" "ido.el"))
342
343;;;###autoload
344(defcustom ido-mode nil
345 "Determines for which functional group \(buffer and files) ido behavior
616e8e5f 346should be enabled. The following values are possible:
337d2b66 347- `buffer': Turn only on ido buffer behavior \(switching, killing,
71296446 348 displaying...)
337d2b66
RS
349- `file': Turn only on ido file behavior \(finding, writing, inserting...)
350- `both': Turn on ido buffer and file behavior.
351- `nil': Turn off any ido switching.
789d1bf0
KS
352
353Setting this variable directly does not take effect;
354use either \\[customize] or the function `ido-mode'."
355 :set #'(lambda (symbol value)
356 (ido-mode value))
7103fd59 357 :initialize 'custom-initialize-default
789d1bf0
KS
358 :require 'ido
359 :link '(emacs-commentary-link "ido.el")
1b00bc64 360 :set-after '(ido-save-directory-list-file
b97f1994 361 ;; This will clear ido-unc-hosts-cache, so set it
1b00bc64 362 ;; before loading history file.
b97f1994 363 ido-unc-hosts)
71296446 364 :type '(choice (const :tag "Turn on only buffer" buffer)
789d1bf0
KS
365 (const :tag "Turn on only file" file)
366 (const :tag "Turn on both buffer and file" both)
367 (const :tag "Switch off all" nil))
368 :group 'ido)
369
789d1bf0 370(defcustom ido-case-fold case-fold-search
9201cc28 371 "Non-nil if searching of buffer and file names should ignore case."
789d1bf0
KS
372 :type 'boolean
373 :group 'ido)
374
375(defcustom ido-ignore-buffers
376 '("\\` ")
9201cc28 377 "List of regexps or functions matching buffer names to ignore.
789d1bf0
KS
378For example, traditional behavior is not to list buffers whose names begin
379with a space, for which the regexp is `\\` '. See the source file for
79164cf4 380example functions that filter buffer names."
789d1bf0
KS
381 :type '(repeat (choice regexp function))
382 :group 'ido)
383
384(defcustom ido-ignore-files
385 '("\\`CVS/" "\\`#" "\\`.#" "\\`\\.\\./" "\\`\\./")
9201cc28 386 "List of regexps or functions matching file names to ignore.
789d1bf0
KS
387For example, traditional behavior is not to list files whose names begin
388with a #, for which the regexp is `\\`#'. See the source file for
389example functions that filter filenames."
390 :type '(repeat (choice regexp function))
391 :group 'ido)
392
393(defcustom ido-ignore-extensions t
9201cc28 394 "Non-nil means ignore files in `completion-ignored-extensions' list."
789d1bf0
KS
395 :type 'boolean
396 :group 'ido)
397
398(defcustom ido-show-dot-for-dired nil
9201cc28 399 "Non-nil means to always put . as the first item in file name lists.
a09e21bf 400This allows the current directory to be opened immediately with `dired'."
789d1bf0
KS
401 :type 'boolean
402 :group 'ido)
403
1de0ae85 404(defcustom ido-file-extensions-order nil
9201cc28 405 "List of file extensions specifying preferred order of file selections.
1de0ae85
KS
406Each element is either a string with `.' as the first char, an empty
407string matching files without extension, or t which is the default order
616e8e5f 408for files with an unlisted file extension."
1de0ae85
KS
409 :type '(repeat (choice string
410 (const :tag "Default order" t)))
411 :group 'ido)
412
789d1bf0
KS
413(defcustom ido-ignore-directories
414 '("\\`CVS/" "\\`\\.\\./" "\\`\\./")
9201cc28 415 "List of regexps or functions matching sub-directory names to ignore."
789d1bf0
KS
416 :type '(repeat (choice regexp function))
417 :group 'ido)
418
419(defcustom ido-ignore-directories-merge nil
9201cc28 420 "List of regexps or functions matching directory names to ignore during merge.
362cdb61 421Directory names matched by one of the regexps in this list are not inserted
789d1bf0
KS
422in merged file and directory lists."
423 :type '(repeat (choice regexp function))
424 :group 'ido)
425
3da360a7
SM
426;; Examples for setting the value of ido-ignore-buffers
427;;(defun ido-ignore-c-mode (name)
428;; "Ignore all c mode buffers -- example function for ido."
429;; (with-current-buffer name
430;; (derived-mode-p 'c-mode)))
431;;
432;;(setq ido-ignore-buffers '("^ " ido-ignore-c-mode))
789d1bf0 433
3da360a7
SM
434;; Examples for setting the value of ido-ignore-files
435;;(setq ido-ignore-files '("^ " "\\.c\\'" "\\.h\\'"))
789d1bf0 436
a11ad595 437(defcustom ido-default-file-method 'raise-frame
9201cc28 438 "How to visit a new file when using `ido-find-file'.
789d1bf0 439Possible values:
a11ad595
KS
440`selected-window' Show new file in selected window
441`other-window' Show new file in another window (same frame)
442`display' Display file in another window without selecting to it
443`other-frame' Show new file in another frame
444`maybe-frame' If a file is visible in another frame, prompt to ask if you
445 you want to see the file in the same window of the current
446 frame or in the other frame
447`raise-frame' If a file is visible in another frame, raise that
448 frame; otherwise, visit the file in the same window"
449 :type '(choice (const :tag "Visit in selected window" selected-window)
450 (const :tag "Visit in other window" other-window)
451 (const :tag "Display (no select) in other window" display)
452 (const :tag "Visit in other frame" other-frame)
453 (const :tag "Ask to visit in other frame" maybe-frame)
454 (const :tag "Raise frame if already visited" raise-frame))
789d1bf0
KS
455 :group 'ido)
456
a11ad595 457(defcustom ido-default-buffer-method 'raise-frame
9201cc28 458 "How to switch to new buffer when using `ido-switch-buffer'.
616e8e5f 459See `ido-default-file-method' for details."
a11ad595
KS
460 :type '(choice (const :tag "Show in selected window" selected-window)
461 (const :tag "Show in other window" other-window)
462 (const :tag "Display (no select) in other window" display)
463 (const :tag "Show in other frame" other-frame)
464 (const :tag "Ask to show in other frame" maybe-frame)
465 (const :tag "Raise frame if already shown" raise-frame))
466 :type '(choice (const selected-window)
467 (const other-window)
789d1bf0 468 (const display)
a11ad595 469 (const other-frame)
789d1bf0 470 (const maybe-frame)
a11ad595 471 (const raise-frame))
789d1bf0
KS
472 :group 'ido)
473
474(defcustom ido-enable-flex-matching nil
9201cc28 475 "Non-nil means that `ido' will do flexible string matching.
789d1bf0
KS
476Flexible matching means that if the entered string does not
477match any item, any item containing the entered characters
478in the given sequence will match."
479 :type 'boolean
480 :group 'ido)
481
482
483(defcustom ido-enable-regexp nil
9201cc28 484 "Non-nil means that `ido' will do regexp matching.
789d1bf0
KS
485Value can be toggled within `ido' using `ido-toggle-regexp'."
486 :type 'boolean
487 :group 'ido)
488
489(defcustom ido-enable-prefix nil
9201cc28 490 "Non-nil means only match if the entered text is a prefix of file name.
79164cf4 491This behavior is like the standard Emacs completion.
29660eb7 492If nil, match if the entered text is an arbitrary substring.
789d1bf0
KS
493Value can be toggled within `ido' using `ido-toggle-prefix'."
494 :type 'boolean
495 :group 'ido)
496
6d8b6cbd 497(defcustom ido-enable-dot-prefix nil
9201cc28 498 "Non-nil means to match leading dot as prefix.
6d8b6cbd
KS
499I.e. hidden files and buffers will match only if you type a dot
500as first char even if `ido-enable-prefix' is nil."
501 :type 'boolean
502 :group 'ido)
503
d81aa76a 504(defcustom ido-confirm-unique-completion nil
9201cc28 505 "Non-nil means that even a unique completion must be confirmed.
d81aa76a
KS
506This means that \\[ido-complete] must always be followed by \\[ido-exit-minibuffer]
507even when there is only one unique completion."
508 :type 'boolean
509 :group 'ido)
510
d1a0acac 511(defcustom ido-cannot-complete-command 'ido-completion-help
9201cc28 512 "Command run when `ido-complete' can't complete any more.
d1a0acac
KS
513The most useful values are `ido-completion-help', which pops up a
514window with completion alternatives, or `ido-next-match' or
515`ido-prev-match', which cycle the buffer list."
516 :type 'function
517 :group 'ido)
518
519
789d1bf0 520(defcustom ido-record-commands t
9201cc28 521 "Non-nil means that `ido' will record commands in command history.
789d1bf0
KS
522Note that the non-ido equivalent command is recorded."
523 :type 'boolean
524 :group 'ido)
525
526(defcustom ido-max-prospects 12
9201cc28 527 "Non-zero means that the prospect list will be limited to that number of items.
789d1bf0 528For a long list of prospects, building the full list for the minibuffer can take a
616e8e5f 529non-negligible amount of time; setting this variable reduces that time."
789d1bf0
KS
530 :type 'integer
531 :group 'ido)
532
a42e9704 533(defcustom ido-max-file-prompt-width 0.35
9201cc28 534 "Non-zero means that the prompt string be limited to that number of characters.
789d1bf0
KS
535If value is a floating point number, it specifies a fraction of the frame width."
536 :type '(choice
537 (integer :tag "Characters" :value 20)
538 (restricted-sexp :tag "Fraction of frame width"
539 :value 0.35
540 :match-alternatives (ido-fractionp)))
541 :group 'ido)
542
543(defcustom ido-max-window-height nil
9201cc28 544 "Non-nil specifies a value to override `max-mini-window-height'."
789d1bf0
KS
545 :type '(choice
546 (const :tag "Don't override" nil)
547 (integer :tag "Number of lines" :value 1)
548 (restricted-sexp
549 :tag "Fraction of window height"
550 :value 0.25
551 :match-alternatives (ido-fractionp)))
552 :group 'ido)
553
554(defcustom ido-enable-last-directory-history t
9201cc28 555 "Non-nil means that `ido' will remember latest selected directory names.
789d1bf0
KS
556See `ido-last-directory-list' and `ido-save-directory-list-file'."
557 :type 'boolean
558 :group 'ido)
559
560(defcustom ido-max-work-directory-list 50
9201cc28 561 "Maximum number of working directories to record.
789d1bf0
KS
562This is the list of directories where files have most recently been opened.
563See `ido-work-directory-list' and `ido-save-directory-list-file'."
564 :type 'integer
565 :group 'ido)
566
567(defcustom ido-work-directory-list-ignore-regexps nil
9201cc28 568 "List of regexps matching directories which should not be recorded.
362cdb61 569Directory names matched by one of the regexps in this list are not inserted in
789d1bf0
KS
570the `ido-work-directory-list' list."
571 :type '(repeat regexp)
572 :group 'ido)
573
bad111c2 574
310682e6 575(defcustom ido-use-filename-at-point nil
9201cc28 576 "Non-nil means that ido shall look for a filename at point.
3c88bdc5 577May use `ffap-guesser' to guess whether text at point is a filename.
310682e6 578If found, use that as the starting point for filename selection."
3c88bdc5
KS
579 :type '(choice
580 (const :tag "Disabled" nil)
581 (const :tag "Guess filename" guess)
582 (other :tag "Use literal filename" t))
310682e6
KS
583 :group 'ido)
584
585
586(defcustom ido-use-url-at-point nil
9201cc28 587 "Non-nil means that ido shall look for a URL at point.
310682e6
KS
588If found, call `find-file-at-point' to visit it."
589 :type 'boolean
590 :group 'ido)
591
592
bad111c2 593(defcustom ido-enable-tramp-completion t
9201cc28 594 "Non-nil means that ido shall perform tramp method and server name completion.
362cdb61 595A tramp file name uses the following syntax: /method:user@host:filename."
bad111c2
KS
596 :type 'boolean
597 :group 'ido)
598
789d1bf0 599(defcustom ido-record-ftp-work-directories t
9201cc28 600 "Non-nil means record ftp file names in the work directory list."
789d1bf0
KS
601 :type 'boolean
602 :group 'ido)
603
604(defcustom ido-merge-ftp-work-directories nil
9201cc28 605 "If nil, merging ignores ftp file names in the work directory list."
789d1bf0
KS
606 :type 'boolean
607 :group 'ido)
608
609(defcustom ido-cache-ftp-work-directory-time 1.0
9201cc28 610 "Maximum time to cache contents of an ftp directory (in hours).
dfebc0ae 611Use C-l in prompt to refresh list.
789d1bf0
KS
612If zero, ftp directories are not cached."
613 :type 'number
614 :group 'ido)
615
616(defcustom ido-slow-ftp-hosts nil
9201cc28 617 "List of slow ftp hosts where ido prompting should not be used.
789d1bf0 618If an ftp host is on this list, ido automatically switches to the non-ido
616e8e5f 619equivalent function, e.g. `find-file' rather than `ido-find-file'."
789d1bf0
KS
620 :type '(repeat string)
621 :group 'ido)
622
623(defcustom ido-slow-ftp-host-regexps nil
9201cc28 624 "List of regexps matching slow ftp hosts (see `ido-slow-ftp-hosts')."
789d1bf0
KS
625 :type '(repeat regexp)
626 :group 'ido)
627
4c2ee078 628(defvar ido-unc-hosts-cache t
d36995c6 629 "Cached value from `ido-unc-hosts' function.")
4c2ee078 630
dfebc0ae 631(defcustom ido-unc-hosts nil
9201cc28 632 "List of known UNC host names to complete after initial //.
4c2ee078
KS
633If value is a function, that function is called to search network for
634hosts on first use of UNC path."
635 :type '(choice (repeat :tag "List of UNC host names" string)
636 (function-item :tag "Use `NET VIEW'"
637 :value ido-unc-hosts-net-view)
638 (function :tag "Your own function"))
639 :set #'(lambda (symbol value)
640 (set symbol value)
641 (setq ido-unc-hosts-cache t))
642 :group 'ido)
643
b97f1994 644(defcustom ido-downcase-unc-hosts t
9201cc28 645 "Non-nil if UNC host names should be downcased."
b97f1994
KS
646 :type 'boolean
647 :group 'ido)
648
4c2ee078 649(defcustom ido-ignore-unc-host-regexps nil
9201cc28 650 "List of regexps matching UNC hosts to ignore.
b97f1994 651Case is ignored if `ido-downcase-unc-hosts' is set."
4c2ee078 652 :type '(repeat regexp)
dfebc0ae
KS
653 :group 'ido)
654
655(defcustom ido-cache-unc-host-shares-time 8.0
9201cc28 656 "Maximum time to cache shares of an UNC host (in hours).
dfebc0ae 657Use C-l in prompt to refresh list.
3903655d 658If zero, UNC host shares are not cached."
dfebc0ae
KS
659 :type 'number
660 :group 'ido)
661
789d1bf0 662(defcustom ido-max-work-file-list 10
9201cc28 663 "Maximum number of names of recently opened files to record.
79164cf4 664This is the list of the file names (sans directory) which have most recently
3903655d 665been opened. See `ido-work-file-list' and `ido-save-directory-list-file'."
789d1bf0
KS
666 :type 'integer
667 :group 'ido)
668
669(defcustom ido-work-directory-match-only t
9201cc28 670 "Non-nil means to skip non-matching directories in the directory history.
789d1bf0
KS
671When some text is already entered at the `ido-find-file' prompt, using
672\\[ido-prev-work-directory] or \\[ido-next-work-directory] will skip directories
673without any matching entries."
674 :type 'boolean
675 :group 'ido)
676
677(defcustom ido-auto-merge-work-directories-length 0
9201cc28 678 "Automatically switch to merged work directories during file name input.
789d1bf0
KS
679The value is number of characters to type before switching to merged mode.
680If zero, the switch happens when no matches are found in the current directory.
681Automatic merging is disabled if the value is negative."
682 :type 'integer
683 :group 'ido)
684
685(defcustom ido-auto-merge-delay-time 0.70
9201cc28 686 "Delay in seconds to wait for more input before doing auto merge."
789d1bf0
KS
687 :type 'number
688 :group 'ido)
689
690(defcustom ido-auto-merge-inhibit-characters-regexp "[][*?~]"
9201cc28 691 "Regexp matching characters which should inhibit automatic merging.
789d1bf0
KS
692When a (partial) file name matches this regexp, merging is inhibited."
693 :type 'regexp
694 :group 'ido)
695
696(defcustom ido-merged-indicator "^"
697 "The string appended to first choice if it has multiple directory choices."
698 :type 'string
699 :group 'ido)
700
701(defcustom ido-max-dir-file-cache 100
9201cc28 702 "Maximum number of working directories to be cached.
a09e21bf 703This is the size of the cache of `file-name-all-completions' results.
789d1bf0
KS
704Each cache entry is time stamped with the modification time of the
705directory. Some systems, like Windows, have unreliable directory
706modification times, so you may choose to disable caching on such
707systems, or explicitly refresh the cache contents using the command
708`ido-reread-directory' command (C-l) in the minibuffer.
709See also `ido-dir-file-cache' and `ido-save-directory-list-file'."
710 :type 'integer
711 :group 'ido)
712
cb65c373 713(defcustom ido-max-directory-size 30000
9201cc28 714 "Maximum size (in bytes) for directories to use ido completion.
cb65c373
KS
715If you enter a directory with a size larger than this size, ido will
716not provide the normal completion. To show the completions, use C-a."
717 :type '(choice (const :tag "No limit" nil)
718 (integer :tag "Size in bytes" 30000))
719 :group 'ido)
720
789d1bf0 721(defcustom ido-rotate-file-list-default nil
9201cc28 722 "Non-nil means that `ido' will always rotate file list to get default in front."
789d1bf0
KS
723 :type 'boolean
724 :group 'ido)
725
5702da69 726(defcustom ido-enter-matching-directory 'only
9201cc28 727 "Additional methods to enter sub-directory of first/only matching item.
5702da69
KS
728If value is 'first, enter first matching sub-directory when typing a slash.
729If value is 'only, typing a slash only enters the sub-directory if it is
730the only matching item.
731If value is t, automatically enter a sub-directory when it is the only
732matching item, even without typing a slash."
71296446 733 :type '(choice (const :tag "Never" nil)
5702da69
KS
734 (const :tag "Slash enters first directory" first)
735 (const :tag "Slash enters first and only directory" only)
736 (other :tag "Always enter unique directory" t))
789d1bf0
KS
737 :group 'ido)
738
789d1bf0 739(defcustom ido-create-new-buffer 'prompt
9201cc28 740 "Specify whether a new buffer is created if no buffer matches substring.
789d1bf0
KS
741Choices are 'always to create new buffers unconditionally, 'prompt to
742ask user whether to create buffer, or 'never to never create new buffer."
71296446 743 :type '(choice (const always)
789d1bf0
KS
744 (const prompt)
745 (const never))
746 :group 'ido)
747
3729cc87 748(defcustom ido-setup-hook nil
9201cc28 749 "Hook run after the ido variables and keymap have been setup.
3729cc87 750The dynamic variable `ido-cur-item' contains the current type of item that
79164cf4 751is read by ido; possible values are file, dir, buffer, and list.
facf67fd 752Additional keys can be defined in `ido-completion-map'."
789d1bf0
KS
753 :type 'hook
754 :group 'ido)
755
756(defcustom ido-separator nil
9201cc28 757 "String used by ido to separate the alternatives in the minibuffer.
789d1bf0 758Obsolete. Set 3rd element of `ido-decorations' instead."
610a4f64 759 :type '(choice string (const nil))
789d1bf0
KS
760 :group 'ido)
761
11c238b3 762(defcustom ido-decorations '( "{" "}" " | " " | ..." "[" "]" " [No match]" " [Matched]" " [Not readable]" " [Too big]" " [Confirm]")
9201cc28 763 "List of strings used by ido to display the alternatives in the minibuffer.
5b54c385 764There are 11 elements in this list:
789d1bf0 7651st and 2nd elements are used as brackets around the prospect list,
a09e21bf 7663rd element is the separator between prospects (ignored if `ido-separator' is set),
789d1bf0
KS
7674th element is the string inserted at the end of a truncated list of prospects,
7685th and 6th elements are used as brackets around the common match string which
769can be completed using TAB,
616e8e5f
JB
7707th element is the string displayed when there are no matches, and
7718th element is displayed if there is a single match (and faces are not used),
7729th element is displayed when the current directory is non-readable,
11c238b3
KS
77310th element is displayed when directory exceeds `ido-max-directory-size',
77411th element is displayed to confirm creating new file or buffer."
789d1bf0
KS
775 :type '(repeat string)
776 :group 'ido)
777
0523d117
JW
778(defcustom ido-use-virtual-buffers nil
779 "If non-nil, refer to past buffers as well as existing ones.
f9a27d86
JW
780Essentially it works as follows: Say you are visiting a file and
781the buffer gets cleaned up by mignight.el. Later, you want to
782switch to that buffer, but find it's no longer open. With
783virtual buffers enabled, the buffer name stays in the buffer
784list (using the ido-virtual face, and always at the end), and if
785you select it, it opens the file back up again. This allows you
786to think less about whether recently opened files are still open
787or not. Most of the time you can quit Emacs, restart, and then
788switch to a file buffer that was previously open as if it still
789were.
790 This feature relies upon the `recentf' package, which will be
0523d117 791enabled if this variable is configured to a non-nil value."
f9a27d86 792 :version "24.1"
0523d117
JW
793 :type 'boolean
794 :group 'ido)
795
789d1bf0 796(defcustom ido-use-faces t
9201cc28 797 "Non-nil means use ido faces to highlighting first match, only match and
789d1bf0
KS
798subdirs in the alternatives."
799 :type 'boolean
800 :group 'ido)
801
ccba8bb6 802(defface ido-first-match '((t (:bold t)))
9201cc28 803 "Face used by ido for highlighting first match."
789d1bf0
KS
804 :group 'ido)
805
ccba8bb6 806(defface ido-only-match '((((class color))
789d1bf0
KS
807 (:foreground "ForestGreen"))
808 (t (:italic t)))
9201cc28 809 "Face used by ido for highlighting only match."
789d1bf0
KS
810 :group 'ido)
811
ccba8bb6 812(defface ido-subdir '((((min-colors 88) (class color))
ea81d57e
DN
813 (:foreground "red1"))
814 (((class color))
789d1bf0
KS
815 (:foreground "red"))
816 (t (:underline t)))
9201cc28 817 "Face used by ido for highlighting subdirs in the alternatives."
789d1bf0
KS
818 :group 'ido)
819
0523d117
JW
820(defface ido-virtual '((t (:inherit font-lock-builtin-face)))
821 "Face used by ido for matching virtual buffer names."
f9a27d86 822 :version "24.1"
0523d117
JW
823 :group 'ido)
824
ccba8bb6 825(defface ido-indicator '((((min-colors 88) (class color))
ea81d57e
DN
826 (:foreground "yellow1"
827 :background "red1"
828 :width condensed))
829 (((class color))
789d1bf0
KS
830 (:foreground "yellow"
831 :background "red"
832 :width condensed))
833 (t (:inverse-video t)))
9201cc28 834 "Face used by ido for highlighting its indicators."
789d1bf0
KS
835 :group 'ido)
836
665ed61a
KS
837(defface ido-incomplete-regexp
838 '((t
839 (:inherit font-lock-warning-face)))
840 "Ido face for indicating incomplete regexps."
841 :group 'ido)
842
789d1bf0 843(defcustom ido-make-file-list-hook nil
9201cc28 844 "List of functions to run when the list of matching files is created.
789d1bf0
KS
845Each function on the list may modify the dynamically bound variable
846`ido-temp-list' which contains the current list of matching files."
847 :type 'hook
848 :group 'ido)
849
850(defcustom ido-make-dir-list-hook nil
9201cc28 851 "List of functions to run when the list of matching directories is created.
789d1bf0
KS
852Each function on the list may modify the dynamically bound variable
853`ido-temp-list' which contains the current list of matching directories."
854 :type 'hook
855 :group 'ido)
856
857(defcustom ido-make-buffer-list-hook nil
9201cc28 858 "List of functions to run when the list of matching buffers is created.
789d1bf0
KS
859Each function on the list may modify the dynamically bound variable
860`ido-temp-list' which contains the current list of matching buffer names."
861 :type 'hook
862 :group 'ido)
863
362cdb61 864(defcustom ido-rewrite-file-prompt-functions nil
9201cc28 865 "List of functions to run when the find-file prompt is created.
789d1bf0
KS
866Each function on the list may modify the following dynamically bound
867variables:
337d2b66
RS
868 dirname - the (abbreviated) directory name
869 to be modified by the hook functions
870 max-width - the max width of the resulting dirname; nil means no limit
871 prompt - the basic prompt (e.g. \"Find File: \")
872 literal - the string shown if doing \"literal\" find; set to nil to omit
79164cf4 873 vc-off - the string shown if version control is inhibited; set to nil to omit
337d2b66
RS
874 prefix - either nil or a fixed prefix for the dirname
875
789d1bf0 876The following variables are available, but should not be changed:
a09e21bf 877 `ido-current-directory' - the unabbreviated directory name
337d2b66 878 item - equals `file' or `dir' depending on the current mode."
789d1bf0
KS
879 :type 'hook
880 :group 'ido)
881
362cdb61
KS
882(defvar ido-rewrite-file-prompt-rules nil
883 "*Alist of rewriting rules for directory names in ido prompts.
884A list of elements of the form (FROM . TO) or (FROM . FUNC), each
885meaning to rewrite the directory name if matched by FROM by either
886substituting the matched string by TO or calling the function FUNC
887with the current directory name as its only argument and using the
888return value as the new directory name. In addition, each FUNC may
889also modify the dynamic variables described for the variable
890`ido-rewrite-file-prompt-functions'.")
789d1bf0
KS
891
892(defcustom ido-completion-buffer "*Ido Completions*"
9201cc28 893 "Name of completion buffer used by ido.
789d1bf0
KS
894Set to nil to disable completion buffers popping up."
895 :type 'string
896 :group 'ido)
897
898(defcustom ido-completion-buffer-all-completions nil
9201cc28 899 "Non-nil means to show all completions in completion buffer.
789d1bf0
KS
900Otherwise, only the current list of matches is shown."
901 :type 'boolean
902 :group 'ido)
903
904(defvar ido-all-frames 'visible
905 "*Argument to pass to `walk-windows' when finding visible files.
906See documentation of `walk-windows' for useful values.")
907
908(defcustom ido-minibuffer-setup-hook nil
9201cc28 909 "Ido-specific customization of minibuffer setup.
789d1bf0 910
4837b516 911This hook is run during minibuffer setup if `ido' is active.
789d1bf0
KS
912It is intended for use in customizing ido for interoperation
913with other packages. For instance:
914
71296446 915 \(add-hook 'ido-minibuffer-setup-hook
789d1bf0
KS
916 \(function
917 \(lambda ()
319a586a
JB
918 \(make-local-variable 'max-mini-window-height)
919 \(setq max-mini-window-height 3))))
789d1bf0 920
319a586a 921will constrain Emacs to a maximum minibuffer height of 3 lines when
789d1bf0
KS
922ido is running. Copied from `icomplete-minibuffer-setup-hook'."
923 :type 'hook
924 :group 'ido)
925
dee11cd2 926(defcustom ido-save-directory-list-file (convert-standard-filename "~/.ido.last")
789d1bf0
KS
927 "File in which the ido state is saved between invocations.
928Variables stored are: `ido-last-directory-list', `ido-work-directory-list',
929`ido-work-file-list', and `ido-dir-file-cache'.
930Must be set before enabling ido mode."
931 :type 'string
932 :group 'ido)
933
934(defcustom ido-read-file-name-as-directory-commands '()
a2cf0212 935 "List of commands which uses `read-file-name' to read a directory name.
789d1bf0 936When `ido-everywhere' is non-nil, the commands in this list will read
616e8e5f 937the directory using `ido-read-directory-name'."
789d1bf0
KS
938 :type '(repeat symbol)
939 :group 'ido)
940
941(defcustom ido-read-file-name-non-ido '()
942 "List of commands which shall not read file names the ido way.
943When `ido-everywhere' is non-nil, the commands in this list will read
616e8e5f 944the file name using normal `read-file-name' style."
789d1bf0
KS
945 :type '(repeat symbol)
946 :group 'ido)
947
b2d4c118
KS
948(defcustom ido-before-fallback-functions '()
949 "List of functions to call before calling a fallback command.
950The fallback command is passed as an argument to the functions."
951 :type 'hook
952 :group 'ido)
953
789d1bf0
KS
954;;; Internal Variables
955
956;; Persistent variables
957
facf67fd 958(defvar ido-completion-map nil
973495ca
KS
959 "Currently active keymap for ido commands.")
960
facf67fd 961(defvar ido-common-completion-map nil
973495ca
KS
962 "Keymap for all ido commands.")
963
facf67fd 964(defvar ido-file-completion-map nil
973495ca
KS
965 "Keymap for ido file commands.")
966
facf67fd 967(defvar ido-file-dir-completion-map nil
973495ca
KS
968 "Keymap for ido file and directory commands.")
969
facf67fd 970(defvar ido-buffer-completion-map nil
973495ca 971 "Keymap for ido buffer commands.")
789d1bf0
KS
972
973(defvar ido-file-history nil
974 "History of files selected using `ido-find-file'.")
975
976(defvar ido-buffer-history nil
977 "History of buffers selected using `ido-switch-buffer'.")
978
789d1bf0 979(defvar ido-last-directory-list nil
362cdb61 980 "List of last selected directory names.
789d1bf0
KS
981See `ido-enable-last-directory-history' for details.")
982
983(defvar ido-work-directory-list nil
362cdb61 984 "List of actual working directory names.
789d1bf0 985The current directory is inserted at the front of this list whenever a
616e8e5f 986file is opened with `ido-find-file' and family.")
789d1bf0
KS
987
988(defvar ido-work-file-list nil
989 "List of actual work file names.
337d2b66
RS
990Opening a file with `ido-find-file' and similar functions
991inserts the current file name (relative to its containing directory)
992at the front of this list.")
789d1bf0
KS
993
994(defvar ido-dir-file-cache nil
337d2b66
RS
995 "List of `file-name-all-completions' results.
996Each element in the list is of the form (DIR (MTIME) FILE...).")
789d1bf0 997
69beb26d
KS
998(defvar ido-ignore-item-temp-list nil
999 "List of items to ignore in current ido invocation.
616e8e5f 1000Intended to be let-bound by functions which call ido repeatedly.
69beb26d
KS
1001Should never be set permanently.")
1002
789d1bf0
KS
1003;; Temporary storage
1004
1005(defvar ido-eoinput 1
1006 "Point where minibuffer input ends and completion info begins.
1007Copied from `icomplete-eoinput'.")
1008(make-variable-buffer-local 'ido-eoinput)
1009
1010(defvar ido-common-match-string nil
1011 "Stores the string that is common to all matching files.")
1012
1013(defvar ido-rescan nil
1014 "Non-nil means we need to regenerate the list of matching items.")
1015
1016(defvar ido-rotate nil
1017 "Non-nil means we are rotating list of matches.")
1018
1019(defvar ido-text nil
1020 "Stores the users string as it is typed in.")
1021
1022(defvar ido-text-init nil
1023 "The initial string for the users string it is typed in.")
1024
3729cc87
KS
1025(defvar ido-input-stack nil
1026 "Stores the users strings when user hits M-b/M-f.")
1027
789d1bf0
KS
1028(defvar ido-matches nil
1029 "List of files currently matching `ido-text'.")
1030
1031(defvar ido-report-no-match t
a2cf0212 1032 "Report [No Match] when no completions matches `ido-text'.")
789d1bf0 1033
71296446
JB
1034(defvar ido-exit nil
1035 "Flag to monitor how `ido-find-file' exits.
789d1bf0
KS
1036If equal to `takeprompt', we use the prompt as the file name to be
1037selected.")
1038
1039(defvar ido-current-directory nil
616e8e5f 1040 "Current directory for `ido-find-file'.")
789d1bf0
KS
1041
1042(defvar ido-auto-merge-timer nil
1043 "Delay timer for auto merge.")
1044
1045(defvar ido-use-mycompletion-depth 0
71296446 1046 "Non-nil means use `ido' completion feedback.
a09e21bf
JB
1047Is set by ido functions to the current `minibuffer-depth',
1048so that it doesn't interfere with other minibuffer usage.")
789d1bf0 1049
665ed61a
KS
1050(defvar ido-incomplete-regexp nil
1051 "Non-nil if an incomplete regexp is entered.")
789d1bf0 1052
155943b9
KS
1053(defvar ido-initial-position nil
1054 "Non-nil means to explicitly cursor on entry to minibuffer.
1055Value is an integer which is number of chars to right of prompt.")
1056
9caf8a8f
JB
1057(defvar ido-virtual-buffers nil
1058 "List of virtual buffers, that is, past visited files.
1059This is a copy of `recentf-list', pared down and with faces applied.
1060Only used if `ido-use-virtual-buffers' is non-nil.")
1061
789d1bf0
KS
1062;;; Variables with dynamic bindings.
1063;;; Declared here to keep the byte compiler quiet.
1064
db9f395b 1065;; Stores the current ido item type ('file, 'dir, 'buffer, or 'list).
789d1bf0
KS
1066(defvar ido-cur-item)
1067
3d37467b
KS
1068;;; Stores the current default item
1069(defvar ido-default-item)
1070
789d1bf0
KS
1071;; Stores the current list of items that will be searched through.
1072;; The list is ordered, so that the most interesting item comes first,
1073;; although by default, the files visible in the current frame are put
2acfb954
ÓF
1074;; at the end of the list.
1075(defvar ido-cur-list nil)
789d1bf0 1076
db9f395b 1077;; Stores the choice list for ido-completing-read
2acfb954 1078(defvar ido-choice-list nil)
db9f395b 1079
789d1bf0
KS
1080;; Stores the list of items which are ignored when building
1081;; `ido-cur-list'. It is in no specific order.
1082(defvar ido-ignored-list)
1083
a70343bd
KS
1084;; Remember if current directory is non-readable (so we cannot do completion).
1085(defvar ido-directory-nonreadable)
1086
cb65c373
KS
1087;; Remember if current directory is 'huge' (so we don't want to do completion).
1088(defvar ido-directory-too-big)
1089
789d1bf0
KS
1090;; Keep current item list if non-nil.
1091(defvar ido-keep-item-list)
1092
1093;; Process ido-ignore-* lists.
1094(defvar ido-process-ignore-lists)
1095
1096;; Don't process ido-ignore- lists once.
1097(defvar ido-process-ignore-lists-inhibit)
1098
1099;; Buffer from which ido was entered.
1100(defvar ido-entry-buffer)
1101
1102;; Non-nil if matching file must be selected.
1103(defvar ido-require-match)
1104
11c238b3
KS
1105;; Non-nil if we should add [confirm] to prompt
1106(defvar ido-show-confirm-message)
1107
789d1bf0
KS
1108;; Stores a temporary version of the file list being created.
1109(defvar ido-temp-list)
1110
1111;; Non-nil if default list element should be rotated into place.
1112(defvar ido-rotate-temp)
1113
1114;; Stores current index in ido-work-directory-list.
1115(defvar ido-work-directory-index)
1116
1117;; Stores current index in ido-work-file-list.
1118(defvar ido-work-file-index)
1119
1120;; Set when merged work directory list is in use.
1121(defvar ido-use-merged-list)
1122
1123;; Set when merged work directory list not yet built.
1124(defvar ido-try-merged-list)
1125
1126;; Saved state prior to last work directory merge.
1127;; Value is a list (ido-text dir cur-list ignored-list matches).
1128(defvar ido-pre-merge-state)
1129
310682e6
KS
1130;; Original value of vc-handled-backends for use in ido-toggle-vc.
1131(defvar ido-saved-vc-hb)
789d1bf0
KS
1132
1133;; Stores temporary state of literal find file.
1134(defvar ido-find-literal)
1135
db9f395b
KS
1136;; Set to 'ignore to inhibit switching between find-file/switch-buffer.
1137(defvar ido-context-switch-command)
789d1bf0 1138
f9a27d86
JW
1139;; Caches list of names generated by `ido-add-virtual-buffers-to-list'
1140(defvar ido-virtual-buffers nil)
1141
789d1bf0
KS
1142;;; FUNCTIONS
1143
1144(defun ido-active (&optional merge)
1145 (if merge
1146 ido-use-merged-list
cba9a3a5
KS
1147 (and (boundp 'ido-completing-read)
1148 (or (featurep 'xemacs)
1149 (= ido-use-mycompletion-depth (minibuffer-depth))))))
789d1bf0
KS
1150
1151(defvar ido-trace-enable nil)
1152
1153(defun ido-trace (p &optional s retval)
1154 (if ido-trace-enable
1155 (let ((b (get-buffer-create " *IDO Trace*"))
1156 (deactivate-mark deactivate-mark))
1157 (save-excursion
1158 (save-restriction
1159 (set-buffer b)
1160 (insert p ": " (if (stringp s) s (format "%S" s)) "\n")))))
1161 retval)
1162
1163(defun ido-toggle-trace (arg)
1164 (interactive "P")
1165 (setq ido-trace-enable (or arg (not ido-trace-enable)))
bad111c2
KS
1166 (if ido-trace-enable
1167 (message "IDO trace on"))
789d1bf0
KS
1168 (let ((b (get-buffer " *IDO Trace*")))
1169 (if b
1170 (if ido-trace-enable
1171 (kill-buffer b)
bad111c2
KS
1172 (pop-to-buffer b t t)
1173 (setq truncate-lines t)))))
1174
10b19e88
KS
1175(defun ido-local-file-exists-p (file)
1176 "Tell if FILE exists locally."
1177 (let (file-name-handler-alist)
1178 (file-exists-p file)))
1179
4c2ee078
KS
1180(defun ido-unc-hosts (&optional query)
1181 "Return list of UNC host names."
b97f1994
KS
1182 (let ((hosts
1183 (cond
1184 ((listp ido-unc-hosts)
1185 ido-unc-hosts) ;; static list or nil
1186 ((listp ido-unc-hosts-cache)
1187 ido-unc-hosts-cache) ;; result of net search
1188 ((and query (fboundp ido-unc-hosts))
1189 (message (propertize "Searching for UNC hosts..." 'face 'highlight))
1190 (setq ido-unc-hosts-cache (funcall ido-unc-hosts))
1191 (message nil)
1192 ido-unc-hosts-cache)
1193 (query
1194 (setq ido-unc-hosts-cache nil))
1195 (t (fboundp ido-unc-hosts)))))
1196 (when query
1197 (let ((case-fold-search ido-downcase-unc-hosts)
1198 res host re-list re)
1199 (while hosts
1200 (setq host (car hosts)
1201 hosts (cdr hosts)
1202 re-list (and ido-process-ignore-lists
1203 ido-ignore-unc-host-regexps))
1204 (while re-list
1205 (setq re (car re-list)
1206 re-list (cdr re-list))
1207 (if (string-match re host)
1208 (setq re-list nil
1209 host nil)))
1210 (when host
1211 (when ido-downcase-unc-hosts
1212 (setq host (downcase host)))
1213 (setq res (cons host res))))
1214 (setq hosts (sort res #'string<))))
1215 hosts))
4c2ee078
KS
1216
1217(defun ido-unc-hosts-net-view ()
1218 "Query network for list of UNC host names using `NET VIEW'."
1219 (let (hosts)
1220 (with-temp-buffer
1221 (shell-command "net view" t)
1222 (goto-char (point-min))
1223 (while (re-search-forward "^\\\\\\\\\\([[:graph:]]+\\)" nil t)
1224 (setq hosts (cons (match-string 1) hosts))))
1225 hosts))
1226
bad111c2 1227(defun ido-is-tramp-root (&optional dir)
bad111c2 1228 (and ido-enable-tramp-completion
c577a4d2
KS
1229 (string-match "\\`/[^/]+[@:]\\'"
1230 (or dir ido-current-directory))))
789d1bf0 1231
dfebc0ae 1232(defun ido-is-unc-root (&optional dir)
4c2ee078 1233 (and (ido-unc-hosts)
dfebc0ae
KS
1234 (string-equal "//"
1235 (or dir ido-current-directory))))
1236
1237(defun ido-is-unc-host (&optional dir)
4c2ee078 1238 (and (ido-unc-hosts)
dfebc0ae
KS
1239 (string-match "\\`//[^/]+/\\'"
1240 (or dir ido-current-directory))))
1241
789d1bf0
KS
1242(defun ido-is-root-directory (&optional dir)
1243 (setq dir (or dir ido-current-directory))
bad111c2
KS
1244 (or
1245 (string-equal "/" dir)
1246 (and (memq system-type '(windows-nt ms-dos))
1247 (string-match "\\`[a-zA-Z]:[/\\]\\'" dir))
1248 (if ido-enable-tramp-completion
1249 (ido-is-tramp-root dir)
1250 (string-match "\\`/[^:/][^:/]+:\\'" dir))))
789d1bf0
KS
1251
1252(defun ido-is-ftp-directory (&optional dir)
71296446 1253 (string-match
bad111c2
KS
1254 (if ido-enable-tramp-completion
1255 "\\`/[^/:][^/:]+:" ;; like tramp-file-name-regexp-unified, but doesn't match single drive letters
1256 "\\`/[^/:][^/:]+:/")
1257 (or dir ido-current-directory)))
789d1bf0
KS
1258
1259(defun ido-is-slow-ftp-host (&optional dir)
1260 (and (or ido-slow-ftp-hosts ido-slow-ftp-host-regexps)
1261 (setq dir (or dir ido-current-directory))
1262 ;; (featurep 'ange-ftp)
1263 ;; (ange-ftp-ftp-name dir)
71296446 1264 (string-match
bad111c2
KS
1265 (if ido-enable-tramp-completion
1266 "\\`/\\([^/]+[@:]\\)*\\([^@/:][^@/:]+\\):"
1267 "\\`/\\([^/:]*@\\)?\\([^@/:][^@/:]+\\):/")
1268 dir)
789d1bf0
KS
1269 (let ((host (substring dir (match-beginning 2) (match-end 2))))
1270 (or (member host ido-slow-ftp-hosts)
1271 (let ((re ido-slow-ftp-host-regexps))
1272 (while (and re (not (string-match (car re) host)))
1273 (setq re (cdr re)))
1274 re)))))
1275
1276(defun ido-time-stamp (&optional time)
1277 ;; Time is a floating point number (fractions of 1 hour)
1278 (setq time (or time (current-time)))
1279 (/ (+ (* (car time) 65536.0) (car (cdr time))) 3600.0))
1280
1281(defun ido-cache-ftp-valid (&optional time)
1282 (and (numberp ido-cache-ftp-work-directory-time)
1283 (> ido-cache-ftp-work-directory-time 0)
1284 (or (not time)
1285 (< (- (ido-time-stamp) time) ido-cache-ftp-work-directory-time))))
1286
dfebc0ae
KS
1287(defun ido-cache-unc-valid (&optional time)
1288 (and (numberp ido-cache-unc-host-shares-time)
1289 (> ido-cache-unc-host-shares-time 0)
1290 (or (not time)
1291 (< (- (ido-time-stamp) time) ido-cache-unc-host-shares-time))))
1292
789d1bf0
KS
1293(defun ido-may-cache-directory (&optional dir)
1294 (setq dir (or dir ido-current-directory))
bad111c2 1295 (cond
cb65c373
KS
1296 ((ido-directory-too-big-p dir)
1297 nil)
bad111c2
KS
1298 ((and (ido-is-root-directory dir)
1299 (or ido-enable-tramp-completion
1300 (memq system-type '(windows-nt ms-dos))))
1301 nil)
dfebc0ae
KS
1302 ((ido-is-unc-host dir)
1303 (ido-cache-unc-valid))
1304 ((ido-is-ftp-directory dir)
1305 (ido-cache-ftp-valid))
1306 (t t)))
789d1bf0
KS
1307
1308(defun ido-pp (list &optional sep)
1309 (let ((print-level nil) (eval-expression-print-level nil)
1310 (print-length nil) (eval-expression-print-length nil))
1311 (insert "\n;; ----- " (symbol-name list) " -----\n(\n ")
1312 (setq list (symbol-value list))
1313 (while list
1314 (let* ((elt (car list))
1315 (s (if (consp elt) (car elt) elt)))
1316 (if (and (stringp s) (= (length s) 0))
1317 (setq s nil))
1318 (if s
1319 (prin1 elt (current-buffer)))
1320 (if (and (setq list (cdr list)) s)
1321 (insert (or sep "\n ")))))
1322 (insert "\n)\n")))
1323
1324(defun ido-save-history ()
1325 "Save ido history and cache information between sessions."
1326 (interactive)
782ea71a
KS
1327 (when (and ido-last-directory-list ido-save-directory-list-file)
1328 (let ((buf (get-buffer-create " *ido session*"))
d725608c 1329 (version-control 'never))
782ea71a
KS
1330 (unwind-protect
1331 (with-current-buffer buf
1332 (erase-buffer)
efccebb5 1333 (insert ";;; -*- coding: utf-8 -*-\n")
d725608c 1334 (setq buffer-file-coding-system 'utf-8)
782ea71a
KS
1335 (ido-pp 'ido-last-directory-list)
1336 (ido-pp 'ido-work-directory-list)
1337 (ido-pp 'ido-work-file-list)
1338 (ido-pp 'ido-dir-file-cache "\n\n ")
1b00bc64
KS
1339 (if (listp ido-unc-hosts-cache)
1340 (ido-pp 'ido-unc-hosts-cache)
1341 (insert "\n;; ----- ido-unc-hosts-cache -----\nt\n"))
789d1bf0 1342 (write-file ido-save-directory-list-file nil))
782ea71a 1343 (kill-buffer buf)))))
789d1bf0
KS
1344
1345(defun ido-load-history (&optional arg)
1346 "Load ido history and cache information from previous session.
1347With prefix argument, reload history unconditionally."
1348 (interactive "P")
1349 (if (or arg (and ido-save-directory-list-file (not ido-last-directory-list)))
1350 (let ((file (expand-file-name ido-save-directory-list-file))
1351 buf)
1352 (when (file-readable-p file)
782ea71a
KS
1353 (setq buf (get-buffer-create " *ido session*"))
1354 (unwind-protect
1355 (with-current-buffer buf
1356 (erase-buffer)
1357 (insert-file-contents file)
1358 (condition-case nil
1359 (setq ido-last-directory-list (read (current-buffer))
1360 ido-work-directory-list (read (current-buffer))
1361 ido-work-file-list (read (current-buffer))
1b00bc64
KS
1362 ido-dir-file-cache (read (current-buffer))
1363 ido-unc-hosts-cache (read (current-buffer)))
782ea71a
KS
1364 (error nil)))
1365 (kill-buffer buf)))))
789d1bf0
KS
1366 (ido-wash-history))
1367
1368(defun ido-wash-history ()
1369 "Clean-up ido history and cache information.
1370Removes badly formatted data and ignored directories."
1371 (interactive)
1372 ;; Check format of each of our lists, discard bogus elements
1373 (setq ido-last-directory-list
1374 (and (listp ido-last-directory-list)
1375 (let ((l ido-last-directory-list) r)
1376 (while l
1377 (if (and (consp (car l))
1378 (stringp (car (car l)))
1379 (stringp (cdr (car l))))
1380 (setq r (cons (car l) r)))
1381 (setq l (cdr l)))
1382 (nreverse r))))
71296446 1383 (setq ido-work-directory-list
789d1bf0
KS
1384 (and (listp ido-work-directory-list)
1385 (let ((l ido-work-directory-list) r)
1386 (while l
1387 (if (and (stringp (car l))
1388 (or ido-record-ftp-work-directories
1389 (not (ido-is-ftp-directory (car l)))))
1390 (setq r (cons (car l) r)))
1391 (setq l (cdr l)))
1392 (nreverse r))))
71296446 1393 (setq ido-work-file-list
789d1bf0
KS
1394 (and (listp ido-work-file-list)
1395 (let ((l ido-work-file-list) r)
1396 (while l
1397 (if (stringp (car l))
1398 (setq r (cons (car l) r)))
1399 (setq l (cdr l)))
1400 (nreverse r))))
71296446 1401 (setq ido-dir-file-cache
789d1bf0
KS
1402 (and (listp ido-dir-file-cache)
1403 (let ((l ido-dir-file-cache) r)
1404 (while l
1405 (if (and (listp (car l))
1406 (> (length (car l)) 2)
1407 (let ((dir (car (car l)))
1408 (time (car (cdr (car l))))
1409 (files (cdr (cdr (car l)))))
1410 (and
1411 (stringp dir)
1412 (consp time)
dfebc0ae
KS
1413 (cond
1414 ((integerp (car time))
1415 (and (/= (car time) 0)
1416 (integerp (car (cdr time)))
1417 (/= (car (cdr time)) 0)
1418 (ido-may-cache-directory dir)))
1419 ((eq (car time) 'ftp)
1420 (and (numberp (cdr time))
789d1bf0
KS
1421 (ido-is-ftp-directory dir)
1422 (ido-cache-ftp-valid (cdr time))))
dfebc0ae
KS
1423 ((eq (car time) 'unc)
1424 (and (numberp (cdr time))
1425 (ido-is-unc-host dir)
1426 (ido-cache-unc-valid (cdr time))))
1427 (t nil))
789d1bf0
KS
1428 (let ((s files) (ok t))
1429 (while s
1430 (if (stringp (car s))
1431 (setq s (cdr s))
1432 (setq s nil ok nil)))
1433 ok))))
1434 (setq r (cons (car l) r)))
1435 (setq l (cdr l)))
1436 (nreverse r))))
1437
1438 ;; Remove ignored directories from work directory list
1439 ;; according to ido-work-directory-list-ignore-regexps
1440 (if ido-work-directory-list
1441 (let ((dirs (reverse ido-work-directory-list)))
1442 (setq ido-work-directory-list nil)
1443 (while dirs
1444 (ido-record-work-directory (car dirs))
1445 (setq dirs (cdr dirs)))))
1446 ;; Get rid of text properties
1447 (let ((l ido-last-directory-list) e)
1448 (while l
1449 (setq e (car l) l (cdr l))
1450 (set-text-properties 0 (length (car e)) nil (car e))
1451 (set-text-properties 0 (length (cdr e)) nil (cdr e))))
1452 (let ((l ido-work-directory-list) e)
1453 (while l
1454 (setq e (car l) l (cdr l))
1455 (set-text-properties 0 (length e) nil e)))
1456 (let ((l ido-work-file-list) e)
1457 (while l
1458 (setq e (car l) l (cdr l))
1459 (set-text-properties 0 (length e) nil e)))
1460 (let ((l ido-dir-file-cache) e d)
1461 (while l
1462 (setq e (car l) l (cdr l))
1463 (if (listp e)
1464 (while e
1465 (setq d (car e) e (cdr e))
1466 (if (not (consp d))
973495ca 1467 (set-text-properties 0 (length d) nil d)))))))
789d1bf0
KS
1468
1469
1470(defun ido-kill-emacs-hook ()
1471 ;; ido kill emacs hook
1472 (ido-save-history))
1473
e78e280d
SM
1474(define-minor-mode ido-everywhere
1475 "Toggle using ido speed-ups everywhere file and directory names are read.
1476With ARG, turn ido speed-up on if arg is positive, off otherwise."
1477 :global t
1478 :group 'ido
1479 (when (get 'ido-everywhere 'file)
1480 (setq read-file-name-function (car (get 'ido-everywhere 'file)))
1481 (put 'ido-everywhere 'file nil))
1482 (when (get 'ido-everywhere 'buffer)
1483 (setq read-buffer-function (car (get 'ido-everywhere 'buffer)))
1484 (put 'ido-everywhere 'buffer nil))
1485 (when ido-everywhere
1486 (when (memq ido-mode '(both file))
1487 (put 'ido-everywhere 'file (cons read-file-name-function nil))
1488 (setq read-file-name-function 'ido-read-file-name))
1489 (when (memq ido-mode '(both buffer))
1490 (put 'ido-everywhere 'buffer (cons read-buffer-function nil))
1491 (setq read-buffer-function 'ido-read-buffer))))
1492
789d1bf0
KS
1493(defvar ido-minor-mode-map-entry nil)
1494
1495;;;###autoload
b0df3884 1496(defun ido-mode (&optional arg)
789d1bf0
KS
1497 "Toggle ido speed-ups on or off.
1498With ARG, turn ido speed-up on if arg is positive, off otherwise.
b0df3884
KS
1499Turning on ido-mode will remap (via a minor-mode keymap) the default
1500keybindings for the `find-file' and `switch-to-buffer' families of
1501commands to the ido versions of these functions.
1502However, if ARG arg equals 'files, remap only commands for files, or
1503if it equals 'buffers, remap only commands for buffer switching.
789d1bf0
KS
1504This function also adds a hook to the minibuffer."
1505 (interactive "P")
1506 (setq ido-mode
71296446 1507 (cond
789d1bf0
KS
1508 ((null arg) (if ido-mode nil 'both))
1509 ((eq arg t) 'both)
1510 ((eq arg 'files) 'file)
1511 ((eq arg 'buffers) 'buffer)
1512 ((memq arg '(file buffer both)) arg)
1513 ((> (prefix-numeric-value arg) 0) 'both)
1514 (t nil)))
1515
1516 (ido-everywhere (if ido-everywhere 1 -1))
973495ca 1517 (when ido-mode
facf67fd 1518 (ido-init-completion-maps))
789d1bf0
KS
1519
1520 (when ido-mode
1521 (add-hook 'minibuffer-setup-hook 'ido-minibuffer-setup)
1522 (add-hook 'choose-completion-string-functions 'ido-choose-completion-string)
1523 (ido-load-history)
1524
1525 (add-hook 'kill-emacs-hook 'ido-kill-emacs-hook)
1526
facf67fd 1527 (let ((map (make-sparse-keymap)))
789d1bf0
KS
1528 (when (memq ido-mode '(file both))
1529 (define-key map [remap find-file] 'ido-find-file)
1530 (define-key map [remap find-file-read-only] 'ido-find-file-read-only)
1531 (define-key map [remap find-alternate-file] 'ido-find-alternate-file)
1532 (define-key map [remap write-file] 'ido-write-file)
1533 (define-key map [remap insert-file] 'ido-insert-file)
1534 (define-key map [remap list-directory] 'ido-list-directory)
1535 (define-key map [remap dired] 'ido-dired)
e78e280d
SM
1536 (define-key map [remap find-file-other-window]
1537 'ido-find-file-other-window)
1538 (define-key map [remap find-file-read-only-other-window]
1539 'ido-find-file-read-only-other-window)
1540 (define-key map [remap find-file-other-frame]
1541 'ido-find-file-other-frame)
1542 (define-key map [remap find-file-read-only-other-frame]
1543 'ido-find-file-read-only-other-frame))
789d1bf0
KS
1544
1545 (when (memq ido-mode '(buffer both))
1546 (define-key map [remap switch-to-buffer] 'ido-switch-buffer)
e78e280d
SM
1547 (define-key map [remap switch-to-buffer-other-window]
1548 'ido-switch-buffer-other-window)
1549 (define-key map [remap switch-to-buffer-other-frame]
1550 'ido-switch-buffer-other-frame)
789d1bf0
KS
1551 (define-key map [remap insert-buffer] 'ido-insert-buffer)
1552 (define-key map [remap kill-buffer] 'ido-kill-buffer)
facf67fd
KS
1553 (define-key map [remap display-buffer] 'ido-display-buffer))
1554
1555 (if ido-minor-mode-map-entry
1556 (setcdr ido-minor-mode-map-entry map)
1557 (setq ido-minor-mode-map-entry (cons 'ido-mode map))
7ff90407
CY
1558 (add-to-list 'minor-mode-map-alist ido-minor-mode-map-entry))))
1559
1560 (message "Ido mode %s" (if ido-mode "enabled" "disabled")))
facf67fd 1561
789d1bf0 1562
71296446 1563;;; IDO KEYMAP
facf67fd
KS
1564(defun ido-init-completion-maps ()
1565 "Set up the completion keymaps used by `ido'."
789d1bf0 1566
973495ca
KS
1567 ;; Common map
1568 (let ((map (make-sparse-keymap)))
789d1bf0
KS
1569 (define-key map "\C-a" 'ido-toggle-ignore)
1570 (define-key map "\C-c" 'ido-toggle-case)
1571 (define-key map "\C-e" 'ido-edit-input)
1572 (define-key map "\t" 'ido-complete)
030fa15b 1573 (define-key map " " 'ido-complete-space)
789d1bf0
KS
1574 (define-key map "\C-j" 'ido-select-text)
1575 (define-key map "\C-m" 'ido-exit-minibuffer)
1576 (define-key map "\C-p" 'ido-toggle-prefix)
1577 (define-key map "\C-r" 'ido-prev-match)
1578 (define-key map "\C-s" 'ido-next-match)
1579 (define-key map "\C-t" 'ido-toggle-regexp)
1580 (define-key map "\C-z" 'ido-undo-merge-work-directory)
bf67f27b 1581 (define-key map [(control ?\s)] 'ido-restrict-to-matches)
a3f4d4d4 1582 (define-key map [(meta ?\s)] 'ido-take-first-match)
08bfde76 1583 (define-key map [(control ?@)] 'ido-restrict-to-matches)
789d1bf0
KS
1584 (define-key map [right] 'ido-next-match)
1585 (define-key map [left] 'ido-prev-match)
1586 (define-key map "?" 'ido-completion-help)
ae9d279d
KS
1587 ;; Magic commands.
1588 (define-key map "\C-b" 'ido-magic-backward-char)
1589 (define-key map "\C-f" 'ido-magic-forward-char)
1590 (define-key map "\C-d" 'ido-magic-delete-char)
973495ca 1591 (set-keymap-parent map minibuffer-local-map)
facf67fd 1592 (setq ido-common-completion-map map))
973495ca
KS
1593
1594 ;; File and directory map
1595 (let ((map (make-sparse-keymap)))
1596 (define-key map "\C-x\C-b" 'ido-enter-switch-buffer)
1597 (define-key map "\C-x\C-f" 'ido-fallback-command)
1598 (define-key map "\C-x\C-d" 'ido-enter-dired)
1599 (define-key map [down] 'ido-next-match-dir)
1600 (define-key map [up] 'ido-prev-match-dir)
1601 (define-key map [(meta up)] 'ido-prev-work-directory)
1602 (define-key map [(meta down)] 'ido-next-work-directory)
1603 (define-key map [backspace] 'ido-delete-backward-updir)
1604 (define-key map "\d" 'ido-delete-backward-updir)
87498551 1605 (define-key map [remap delete-backward-char] 'ido-delete-backward-updir) ; BS
542b315f
KS
1606 (define-key map [remap backward-kill-word] 'ido-delete-backward-word-updir) ; M-DEL
1607
973495ca
KS
1608 (define-key map [(control backspace)] 'ido-up-directory)
1609 (define-key map "\C-l" 'ido-reread-directory)
1610 (define-key map [(meta ?d)] 'ido-wide-find-dir-or-delete-dir)
1611 (define-key map [(meta ?b)] 'ido-push-dir)
a3f4d4d4 1612 (define-key map [(meta ?v)] 'ido-push-dir-first)
973495ca
KS
1613 (define-key map [(meta ?f)] 'ido-wide-find-file-or-pop-dir)
1614 (define-key map [(meta ?k)] 'ido-forget-work-directory)
1615 (define-key map [(meta ?m)] 'ido-make-directory)
1616 (define-key map [(meta ?n)] 'ido-next-work-directory)
1617 (define-key map [(meta ?o)] 'ido-prev-work-file)
1618 (define-key map [(meta control ?o)] 'ido-next-work-file)
1619 (define-key map [(meta ?p)] 'ido-prev-work-directory)
1620 (define-key map [(meta ?s)] 'ido-merge-work-directories)
facf67fd
KS
1621 (set-keymap-parent map ido-common-completion-map)
1622 (setq ido-file-dir-completion-map map))
973495ca
KS
1623
1624 ;; File only map
1625 (let ((map (make-sparse-keymap)))
1626 (define-key map "\C-k" 'ido-delete-file-at-head)
1627 (define-key map "\C-o" 'ido-copy-current-word)
1628 (define-key map "\C-w" 'ido-copy-current-file-name)
1629 (define-key map [(meta ?l)] 'ido-toggle-literal)
1630 (define-key map "\C-v" 'ido-toggle-vc)
facf67fd
KS
1631 (set-keymap-parent map ido-file-dir-completion-map)
1632 (setq ido-file-completion-map map))
973495ca
KS
1633
1634 ;; Buffer map
1635 (let ((map (make-sparse-keymap)))
1636 (define-key map "\C-x\C-f" 'ido-enter-find-file)
1637 (define-key map "\C-x\C-b" 'ido-fallback-command)
1638 (define-key map "\C-k" 'ido-kill-buffer-at-head)
facf67fd
KS
1639 (set-keymap-parent map ido-common-completion-map)
1640 (setq ido-buffer-completion-map map)))
ae9d279d 1641
789d1bf0 1642
facf67fd 1643(defun ido-setup-completion-map ()
973495ca 1644 "Set up the keymap for `ido'."
789d1bf0 1645
973495ca
KS
1646 ;; generated every time so that it can inherit new functions.
1647 (let ((map (make-sparse-keymap))
1648 (viper-p (if (boundp 'viper-mode) viper-mode)))
789d1bf0 1649
973495ca
KS
1650 (when viper-p
1651 (define-key map [remap viper-intercept-ESC-key] 'ignore))
1652
1653 (cond
1654 ((memq ido-cur-item '(file dir))
1655 (when ido-context-switch-command
1656 (define-key map "\C-x\C-b" ido-context-switch-command)
1657 (define-key map "\C-x\C-d" 'ignore))
1658 (when viper-p
9f781d7e
KS
1659 (define-key map [remap viper-backward-char] 'ido-delete-backward-updir)
1660 (define-key map [remap viper-del-backward-char-in-insert] 'ido-delete-backward-updir)
973495ca
KS
1661 (define-key map [remap viper-delete-backward-word] 'ido-delete-backward-word-updir))
1662 (set-keymap-parent map
1663 (if (eq ido-cur-item 'file)
facf67fd
KS
1664 ido-file-completion-map
1665 ido-file-dir-completion-map)))
973495ca
KS
1666
1667 ((eq ido-cur-item 'buffer)
1668 (when ido-context-switch-command
1669 (define-key map "\C-x\C-f" ido-context-switch-command))
facf67fd 1670 (set-keymap-parent map ido-buffer-completion-map))
973495ca
KS
1671
1672 (t
facf67fd 1673 (set-keymap-parent map ido-common-completion-map)))
f0a73ccc 1674
facf67fd 1675 (setq ido-completion-map map)))
789d1bf0
KS
1676
1677(defun ido-final-slash (dir &optional fix-it)
1678 ;; return DIR if DIR has final slash.
1679 ;; else if FIX-IT is non-nil, return DIR/
1680 ;; else return nil.
1681 (setq dir (ido-name dir))
1682 (cond
1683 ((string-match "/\\'" dir) dir)
bad111c2 1684 ((ido-is-tramp-root dir) dir)
789d1bf0
KS
1685 (fix-it (concat dir "/"))
1686 (t nil)))
1687
310682e6
KS
1688(defun ido-no-final-slash (s)
1689 ;; Remove optional final slash from string S
1690 (let ((l (1- (length s))))
1691 (if (and (> l 0) (eq (aref s l) ?/))
1692 (substring s 0 l)
1693 s)))
1694
866f2239
KS
1695(defun ido-nonreadable-directory-p (dir)
1696 ;; Return t if dir is a directory, but not readable
1697 ;; Do not check for non-readable directories via tramp, as this causes a premature
1698 ;; connect on incomplete tramp paths (after entring just method:).
1699 (let ((ido-enable-tramp-completion nil))
1700 (and (ido-final-slash dir)
dfebc0ae 1701 (not (ido-is-unc-host dir))
866f2239
KS
1702 (file-directory-p dir)
1703 (not (file-readable-p dir)))))
1704
cb65c373
KS
1705(defun ido-directory-too-big-p (dir)
1706 ;; Return t if dir is a directory, but too big to show
1707 ;; Do not check for non-readable directories via tramp, as this causes a premature
1708 ;; connect on incomplete tramp paths (after entring just method:).
1709 (let ((ido-enable-tramp-completion nil))
1710 (and (numberp ido-max-directory-size)
1711 (ido-final-slash dir)
dfebc0ae 1712 (not (ido-is-unc-host dir))
cb65c373
KS
1713 (file-directory-p dir)
1714 (> (nth 7 (file-attributes dir)) ido-max-directory-size))))
1715
789d1bf0
KS
1716(defun ido-set-current-directory (dir &optional subdir no-merge)
1717 ;; Set ido's current directory to DIR or DIR/SUBDIR
c577a4d2
KS
1718 (unless (and ido-enable-tramp-completion
1719 (string-match "\\`/[^/]*@\\'" dir))
1720 (setq dir (ido-final-slash dir t)))
789d1bf0
KS
1721 (setq ido-use-merged-list nil
1722 ido-try-merged-list (not no-merge))
c577a4d2
KS
1723 (when subdir
1724 (setq dir (concat dir subdir))
1725 (unless (and ido-enable-tramp-completion
1726 (string-match "\\`/[^/]*@\\'" dir))
1727 (setq dir (ido-final-slash dir t))))
dfebc0ae
KS
1728 (if (get-buffer ido-completion-buffer)
1729 (kill-buffer ido-completion-buffer))
1730 (cond
1731 ((equal dir ido-current-directory)
1732 nil)
1733 ((ido-is-unc-root dir)
1734 (ido-trace "unc" dir)
1735 (setq ido-current-directory dir)
1736 (setq ido-directory-nonreadable nil)
1737 (setq ido-directory-too-big nil)
1738 t)
1739 (t
789d1bf0
KS
1740 (ido-trace "cd" dir)
1741 (setq ido-current-directory dir)
1742 (if (get-buffer ido-completion-buffer)
1743 (kill-buffer ido-completion-buffer))
866f2239 1744 (setq ido-directory-nonreadable (ido-nonreadable-directory-p dir))
cb65c373
KS
1745 (setq ido-directory-too-big (and (not ido-directory-nonreadable)
1746 (ido-directory-too-big-p dir)))
dfebc0ae 1747 t)))
789d1bf0
KS
1748
1749(defun ido-set-current-home (&optional dir)
1750 ;; Set ido's current directory to user's home directory
1751 (ido-set-current-directory (expand-file-name (or dir "~/"))))
1752
1753(defun ido-record-command (command arg)
1754 ;; Add (command arg) to command-history if ido-record-commands is t
1755 (if ido-record-commands
1756 (let ((cmd (list command arg)))
1757 (if (or (not command-history)
1758 (not (equal cmd (car command-history))))
1759 (setq command-history (cons cmd command-history))))))
1760
1761(defun ido-make-prompt (item prompt)
1762 ;; Make the prompt for ido-read-internal
1763 (cond
1764 ((and (memq item '(file dir)) ido-current-directory)
362cdb61 1765 (let ((dirname (abbreviate-file-name ido-current-directory))
a42e9704
KS
1766 (max-width (if (and ido-max-file-prompt-width (floatp ido-max-file-prompt-width))
1767 (floor (* (frame-width) ido-max-file-prompt-width))
1768 ido-max-file-prompt-width))
789d1bf0 1769 (literal (and (boundp 'ido-find-literal) ido-find-literal "(literal) "))
310682e6 1770 (vc-off (and ido-saved-vc-hb (not vc-handled-backends) "[-VC] "))
789d1bf0 1771 (prefix nil)
362cdb61 1772 (rule ido-rewrite-file-prompt-rules))
789d1bf0
KS
1773 (let ((case-fold-search nil))
1774 (while rule
1775 (if (and (consp (car rule))
362cdb61
KS
1776 (string-match (car (car rule)) dirname))
1777 (setq dirname
789d1bf0 1778 (if (stringp (cdr (car rule)))
362cdb61
KS
1779 (replace-match (cdr (car rule)) t nil dirname)
1780 (funcall (cdr (car rule)) dirname))))
789d1bf0 1781 (setq rule (cdr rule))))
362cdb61 1782 (run-hooks 'ido-rewrite-file-prompt-functions)
71296446 1783 (concat prompt
789d1bf0
KS
1784 ; (if ido-process-ignore-lists "" "&")
1785 (or literal "")
1786 (or vc-off "")
1787 (or prefix "")
362cdb61 1788 (let ((l (length dirname)))
789d1bf0 1789 (if (and max-width (> max-width 0) (> l max-width))
71296446 1790 (let* ((s (substring dirname (- max-width)))
789d1bf0
KS
1791 (i (string-match "/" s)))
1792 (concat "..." (if i (substring s i) s)))
362cdb61 1793 dirname)))))
789d1bf0
KS
1794 (t prompt)))
1795
1796;; Here is very briefly how ido-find-file works:
1797;;
1798;; (ido-find-file)
1799;; (ido-file-internal method)
1800;; set ido-current-directory
1801;; (ido-read-internal 'file ...)
1802;; (while ...
1803;; (ido-make-item-list ...)
1804;; (ido-set-matches)
1805;; (completing-read ... ido-text-init ...)
1806;;
1807;; ... here user is allowed to type characters and commands
1808;; a command may set ido-exit and call (exit-minibuffer)
1809;; to make ido-read-internal do advanced tasks (or return)
1810;;
1811;; ... ido-tidy and ido-exhibit are pre- and post-hooks
1812;; which are run before and after each user command.
1813;;
1814;; return value from completing-read is stored in ido-final-text
1815;; - ido-exit may cause further actions to be taken:
1816;; 'refresh - repeat loop (make-item-list, set-matches)
1817;; 'edit - edit the prompt string, then repeat loop
1818;; 'keep - repeat loop but don't (re)make-item-list
1819;; 'updir - go up one directory, repeat loop
1820;; else set ido-selected based on ido-final-text,
1821;; optionally update ido-current-directory and repeat loop, or
1822;; exit with the return value of ido-selected (file name)
1823;; selected file name is returned from ido-read-internal,
1824;; ido-exit and method determines what action is taken
1825;; e.g. the file name may be ignored or joined with ido-current-directory, and
1826;; the relevant function is called (find-file, write-file, etc).
1827
1828(defun ido-read-internal (item prompt history &optional default require-match initial)
a2cf0212 1829 "Perform the `ido-read-buffer' and `ido-read-file-name' functions.
71296446 1830Return the name of a buffer or file selected.
789d1bf0 1831PROMPT is the prompt to give to the user.
2d38f869 1832DEFAULT if given is the default item to start with.
789d1bf0
KS
1833If REQUIRE-MATCH is non-nil, an existing file must be selected.
1834If INITIAL is non-nil, it specifies the initial input string."
1835 (let
1836 ((ido-cur-item item)
1837 (ido-entry-buffer (current-buffer))
1838 (ido-process-ignore-lists t)
1839 (ido-process-ignore-lists-inhibit nil)
1840 (ido-set-default-item t)
1841 ido-default-item
1842 ido-selected
1843 ido-final-text
1844 (done nil)
1845 (icomplete-mode nil) ;; prevent icomplete starting up
1846 ;; Exported dynamic variables:
1847 ido-cur-list
1848 ido-ignored-list
1849 (ido-rotate-temp nil)
1850 (ido-keep-item-list nil)
1851 (ido-use-merged-list nil)
1852 (ido-try-merged-list t)
1853 (ido-pre-merge-state nil)
1854 (ido-case-fold ido-case-fold)
1855 (ido-enable-prefix ido-enable-prefix)
1856 (ido-enable-regexp ido-enable-regexp)
11c238b3 1857 (ido-show-confirm-message nil)
789d1bf0
KS
1858 )
1859
facf67fd 1860 (ido-setup-completion-map)
789d1bf0 1861 (setq ido-text-init initial)
3729cc87
KS
1862 (setq ido-input-stack nil)
1863
1864 (run-hooks 'ido-setup-hook)
1865
789d1bf0 1866 (while (not done)
bad111c2 1867 (ido-trace "\n_LOOP_" ido-text-init)
789d1bf0
KS
1868 (setq ido-exit nil)
1869 (setq ido-rescan t)
1870 (setq ido-rotate nil)
1871 (setq ido-text "")
69beb26d
KS
1872 (when ido-set-default-item
1873 (setq ido-default-item
1874 (cond
1875 ((eq item 'buffer)
1876 (if (bufferp default) (buffer-name default) default))
2d38f869
KS
1877 ((stringp default)
1878 (if (memq item '(file dir))
1879 (file-name-nondirectory default)
1880 default))
69beb26d 1881 ((eq item 'file)
71296446 1882 (and ido-enable-last-directory-history
69beb26d
KS
1883 (let ((d (assoc ido-current-directory ido-last-directory-list)))
1884 (and d (cdr d)))))))
1885 (if (member ido-default-item ido-ignore-item-temp-list)
1886 (setq ido-default-item nil))
5444f278 1887 (ido-trace "new default" ido-default-item)
155943b9
KS
1888 (if ido-default-item
1889 (setq ido-initial-position 0))
69beb26d 1890 (setq ido-set-default-item nil))
789d1bf0
KS
1891
1892 (if ido-process-ignore-lists-inhibit
1893 (setq ido-process-ignore-lists nil))
1894
1895 (if (and ido-use-merged-list (memq ido-try-merged-list '(t wide)) (not ido-keep-item-list))
1896 (let ((olist ido-cur-list)
1897 (oign ido-ignored-list)
1898 (omat ido-matches)
1899 (l (ido-make-merged-file-list ido-text-init
1900 (eq ido-use-merged-list 'auto)
1901 (eq ido-try-merged-list 'wide))))
ec441ab5 1902 (ido-trace "merged" l)
789d1bf0
KS
1903 (cond
1904 ((not l)
1905 (if (eq ido-try-merged-list 'wide)
1906 (setq ido-pre-merge-state
1907 (list "" ido-current-directory olist oign omat)
1908 ido-cur-list nil
1909 ido-ignored-list nil
1910 ido-matches nil
1911 ido-keep-item-list t
1912 ido-try-merged-list (if (eq ido-use-merged-list 'auto) 'auto nil)
1913 ido-use-merged-list nil)
1914 (setq ido-cur-list olist
1915 ido-ignored-list oign
1916 ido-matches omat
1917 ido-keep-item-list t
1918 ido-try-merged-list (if (eq ido-use-merged-list 'auto) 'auto nil)
1919 ido-use-merged-list nil)))
1920 ((eq l t)
1921 (setq ido-use-merged-list nil))
ec441ab5
KS
1922 ((eq l 'input-pending-p)
1923 (setq ido-try-merged-list t
1924 ido-use-merged-list nil))
789d1bf0
KS
1925 (t
1926 (setq ido-pre-merge-state
1927 (list ido-text-init ido-current-directory olist oign omat))
1928 (ido-set-current-directory (car (cdr (car l))))
1929 (if (ido-final-slash ido-text-init)
1930 (setq ido-text-init ""))
1931 (setq ido-cur-list l
1932 ido-ignored-list nil
1933 ido-matches l
1934 ido-rescan nil
1935 ido-keep-item-list t
1936 ido-use-merged-list t)
1937 (ido-trace "Merged" t)
1938 ))))
71296446 1939
789d1bf0
KS
1940 (cond
1941 (ido-keep-item-list
1942 (setq ido-keep-item-list nil
1943 ido-rescan nil))
1944 ((eq ido-cur-item 'file)
1945 (setq ido-ignored-list nil
cb65c373
KS
1946 ido-cur-list (and (not ido-directory-nonreadable)
1947 (not ido-directory-too-big)
1948 (ido-make-file-list ido-default-item))))
789d1bf0
KS
1949 ((eq ido-cur-item 'dir)
1950 (setq ido-ignored-list nil
cb65c373
KS
1951 ido-cur-list (and (not ido-directory-nonreadable)
1952 (not ido-directory-too-big)
1953 (ido-make-dir-list ido-default-item))))
789d1bf0
KS
1954 ((eq ido-cur-item 'buffer)
1955 (setq ido-ignored-list nil
1956 ido-cur-list (ido-make-buffer-list ido-default-item)))
db9f395b
KS
1957 ((eq ido-cur-item 'list)
1958 (setq ido-ignored-list nil
1959 ido-cur-list (ido-make-choice-list ido-default-item)))
789d1bf0
KS
1960 (t nil))
1961 (setq ido-rotate-temp nil)
1962
1963 (if ido-process-ignore-lists-inhibit
1964 (setq ido-process-ignore-lists t
1965 ido-process-ignore-lists-inhibit nil))
1966
1967 (ido-set-matches)
1968 (if (and ido-matches (eq ido-try-merged-list 'auto))
1969 (setq ido-try-merged-list t))
71296446 1970 (let
523c54f5
KS
1971 ((minibuffer-local-completion-map
1972 (if (memq ido-cur-item '(file dir))
1973 minibuffer-local-completion-map
1974 ido-completion-map))
1975 (minibuffer-local-filename-completion-map
1976 (if (memq ido-cur-item '(file dir))
1977 ido-completion-map
1978 minibuffer-local-filename-completion-map))
789d1bf0
KS
1979 (max-mini-window-height (or ido-max-window-height
1980 (and (boundp 'max-mini-window-height) max-mini-window-height)))
1981 (ido-completing-read t)
1982 (ido-require-match require-match)
1983 (ido-use-mycompletion-depth (1+ (minibuffer-depth)))
1984 (show-paren-mode nil))
1985 ;; prompt the user for the file name
1986 (setq ido-exit nil)
1987 (setq ido-final-text
1988 (catch 'ido
71296446 1989 (completing-read
789d1bf0 1990 (ido-make-prompt item prompt)
9066a4d0 1991 '(("dummy" . 1)) nil nil ; table predicate require-match
789d1bf0
KS
1992 (prog1 ido-text-init (setq ido-text-init nil)) ;initial-contents
1993 history))))
1994 (ido-trace "completing-read" ido-final-text)
1995 (if (get-buffer ido-completion-buffer)
1996 (kill-buffer ido-completion-buffer))
1997
1998 (ido-trace "\n_EXIT_" ido-exit)
1999
2000 (cond
2001 ((eq ido-exit 'refresh)
71296446 2002 (if (and (eq ido-use-merged-list 'auto)
789d1bf0
KS
2003 (or (input-pending-p)))
2004 (setq ido-use-merged-list nil
2005 ido-keep-item-list t))
2006 nil)
2007
2008 ((eq ido-exit 'done)
2009 (setq done t
2010 ido-selected ido-text
2011 ido-exit nil))
2012
2013 ((memq ido-exit '(edit chdir))
71296446 2014 (cond
789d1bf0 2015 ((memq ido-cur-item '(file dir))
3f2b52ad 2016 (let* ((read-file-name-function nil)
789d1bf0
KS
2017 (edit (eq ido-exit 'edit))
2018 (d ido-current-directory)
2019 (f ido-text-init)
84f6c6d0 2020 (new t))
789d1bf0 2021 (setq ido-text-init "")
84f6c6d0
KS
2022 (while new
2023 (setq new (if edit
3729cc87
KS
2024 (condition-case nil
2025 (read-file-name (concat prompt "[EDIT] ")
2026 (expand-file-name d)
2027 (concat d f) nil f)
2028 (quit (concat d f)))
789d1bf0 2029 f)
84f6c6d0
KS
2030 d (or (file-name-directory new) "/")
2031 f (file-name-nondirectory new)
789d1bf0 2032 edit t)
71296446 2033 (if (or
789d1bf0
KS
2034 (file-directory-p d)
2035 (and (yes-or-no-p (format "Create directory %s? " d))
71296446 2036 (condition-case nil
789d1bf0
KS
2037 (progn (make-directory d t) t)
2038 (error
2039 (message "Could not create directory")
2040 (sit-for 1)
2041 nil))))
2042 (progn
2043 (ido-set-current-directory d nil (eq ido-exit 'chdir))
2044 (setq ido-text-init f
84f6c6d0 2045 new nil))))))
789d1bf0 2046 (t
3729cc87
KS
2047 (setq ido-text-init
2048 (condition-case nil
2049 (read-string (concat prompt "[EDIT] ") ido-final-text)
2050 (quit ido-final-text)))))
2051
789d1bf0
KS
2052 nil)
2053
2054 ((eq ido-exit 'keep)
2055 (setq ido-keep-item-list t))
2056
db9f395b 2057 ((memq ido-exit '(dired fallback find-file switch-to-buffer insert-buffer insert-file))
789d1bf0
KS
2058 (setq done t))
2059
3729cc87 2060 ((memq ido-exit '(updir push))
789d1bf0
KS
2061 ;; cannot go up if already at the root-dir (Unix) or at the
2062 ;; root-dir of a certain drive (Windows or MS-DOS).
bad111c2
KS
2063 (if (ido-is-tramp-root)
2064 (when (string-match "\\`\\(/\\([^/]+[:@]\\)*\\)\\([^/]+\\)[:@]\\'" ido-current-directory)
2065 (setq ido-text-init (match-string 3 ido-current-directory))
2066 (ido-set-current-directory (match-string 1 ido-current-directory))
2067 (setq ido-set-default-item t))
2068 (unless (ido-is-root-directory)
3729cc87
KS
2069 (when (eq ido-exit 'push)
2070 (setq ido-input-stack (cons (cons ido-cur-item ido-text) ido-input-stack))
2071 (setq ido-cur-item 'dir)
2072 (setq ido-text-init (file-name-nondirectory (substring ido-current-directory 0 -1)))
2073 (ido-trace "push" ido-input-stack))
bad111c2
KS
2074 (ido-set-current-directory (file-name-directory (substring ido-current-directory 0 -1)))
2075 (setq ido-set-default-item t))))
789d1bf0 2076
3729cc87
KS
2077 ((eq ido-exit 'pop)
2078 (ido-trace "pop" ido-input-stack)
2079 (let ((elt (car ido-input-stack)))
2080 (setq ido-input-stack (cdr ido-input-stack))
2081 (ido-set-current-directory (concat ido-current-directory ido-text))
2082 (setq ido-cur-item (car elt))
2083 (setq ido-text-init (cdr elt))))
2084
2085 ((eq ido-exit 'pop-all)
2086 (ido-trace "pop-all" ido-input-stack)
2087 (while ido-input-stack
2088 (let ((elt (car ido-input-stack)))
2089 (setq ido-input-stack (cdr ido-input-stack))
2090 (ido-set-current-directory (concat ido-current-directory ido-text))
2091 (setq ido-cur-item (car elt))
2092 (setq ido-text-init (cdr elt)))))
2093
789d1bf0 2094 ;; Handling the require-match must be done in a better way.
b3da0db5 2095 ((and require-match
11c238b3 2096 (not (memq require-match '(confirm confirm-after-completion)))
b3da0db5
KS
2097 (not (if ido-directory-too-big
2098 (file-exists-p (concat ido-current-directory ido-final-text))
2099 (ido-existing-item-p))))
a09e21bf 2100 (error "Must specify valid item"))
789d1bf0
KS
2101
2102 (t
2103 (setq ido-selected
69beb26d
KS
2104 (if (or (eq ido-exit 'takeprompt)
2105 (null ido-matches))
2106 ido-final-text
2107 ;; else take head of list
2108 (ido-name (car ido-matches))))
789d1bf0
KS
2109
2110 (cond
2a5095fb 2111 ((memq item '(buffer list))
789d1bf0
KS
2112 (setq done t))
2113
2114 ((string-equal "./" ido-selected)
2115 nil)
2116
2117 ((string-equal "../" ido-selected)
2118 ;; cannot go up if already at the root-dir (Unix) or at the
2119 ;; root-dir of a certain drive (Windows or MS-DOS).
2120 (or (ido-is-root-directory)
2121 (ido-set-current-directory (file-name-directory (substring ido-current-directory 0 -1))))
2122 (setq ido-set-default-item t))
bad111c2 2123
10b19e88
KS
2124 ((and (string-match (if ido-enable-tramp-completion ".[:@]\\'" ".:\\'") ido-selected)
2125 (ido-is-root-directory) ;; Ange-ftp or Tramp
2126 (not (ido-local-file-exists-p ido-selected)))
bad111c2
KS
2127 (ido-set-current-directory ido-current-directory ido-selected)
2128 (ido-trace "tramp prefix" ido-selected)
789d1bf0
KS
2129 (if (ido-is-slow-ftp-host)
2130 (setq ido-exit 'fallback
2131 done t)
2132 (setq ido-set-default-item t)))
dfebc0ae 2133
789d1bf0
KS
2134 ((or (string-match "[/\\][^/\\]" ido-selected)
2135 (and (memq system-type '(windows-nt ms-dos))
10b19e88 2136 (string-match "\\`[a-zA-Z]:" ido-selected)))
789d1bf0
KS
2137 (ido-set-current-directory (file-name-directory ido-selected))
2138 (setq ido-set-default-item t))
2139
2140 ((string-match "\\`~" ido-selected)
2141 (ido-set-current-home ido-selected))
2142
2143 ((ido-final-slash ido-selected)
2144 (if ido-enable-last-directory-history
2145 (let ((x (assoc ido-current-directory ido-last-directory-list)))
2146 (if x
2147 (setcdr x ido-selected)
2148 (setq ido-last-directory-list
2149 (cons (cons ido-current-directory ido-selected) ido-last-directory-list)))))
2150 (ido-set-current-directory ido-current-directory ido-selected)
3729cc87 2151 (if ido-input-stack
11ae5e81
KS
2152 ; automatically pop stack elements which match existing files or directories
2153 (let (elt)
2154 (while (and (setq elt (car ido-input-stack))
2155 (file-exists-p (concat ido-current-directory (cdr elt))))
3729cc87
KS
2156 (if (setq ido-input-stack (cdr ido-input-stack))
2157 (ido-set-current-directory ido-current-directory (cdr elt))
2158 (setq ido-text-init (cdr elt)))
2159 (setq ido-cur-item (car elt))))
2160 (setq ido-set-default-item t)))
789d1bf0
KS
2161
2162 (t
2163 (setq done t))))))
2164 ido-selected))
2165
2166(defun ido-edit-input ()
155943b9
KS
2167 "Edit absolute file name entered so far with ido; terminate by RET.
2168If cursor is not at the end of the user input, move to end of input."
789d1bf0 2169 (interactive)
155943b9
KS
2170 (if (not (eobp))
2171 (end-of-line)
2172 (setq ido-text-init (if ido-matches (ido-name (car ido-matches)) ido-text))
2173 (setq ido-exit 'edit)
2174 (exit-minibuffer)))
789d1bf0
KS
2175
2176;;; MAIN FUNCTIONS
db9f395b 2177(defun ido-buffer-internal (method &optional fallback prompt default initial switch-cmd)
789d1bf0
KS
2178 ;; Internal function for ido-switch-buffer and friends
2179 (if (not ido-mode)
b2d4c118
KS
2180 (progn
2181 (run-hook-with-args 'ido-before-fallback-functions
2182 (or fallback 'switch-to-buffer))
2183 (call-interactively (or fallback 'switch-to-buffer)))
db9f395b 2184 (let* ((ido-context-switch-command switch-cmd)
cb65c373
KS
2185 (ido-current-directory nil)
2186 (ido-directory-nonreadable nil)
2187 (ido-directory-too-big nil)
11c238b3
KS
2188 (require-match (confirm-nonexistent-file-or-buffer))
2189 (buf (ido-read-internal 'buffer (or prompt "Buffer: ") 'ido-buffer-history default
0523d117
JW
2190 require-match initial))
2191 filename)
789d1bf0
KS
2192
2193 ;; Choose the buffer name: either the text typed in, or the head
2194 ;; of the list of matches
2195
71296446 2196 (cond
db9f395b 2197 ((eq ido-exit 'find-file)
7d046dbb
KS
2198 (ido-file-internal
2199 (if (memq method '(other-window other-frame)) method ido-default-file-method)
2200 nil nil nil nil ido-text))
789d1bf0 2201
db9f395b
KS
2202 ((eq ido-exit 'insert-file)
2203 (ido-file-internal 'insert 'insert-file nil "Insert file: " nil ido-text 'ido-enter-insert-buffer))
2204
789d1bf0
KS
2205 ((eq ido-exit 'fallback)
2206 (let ((read-buffer-function nil))
16f462c5
KS
2207 (setq this-command (or fallback 'switch-to-buffer))
2208 (run-hook-with-args 'ido-before-fallback-functions this-command)
2209 (call-interactively this-command)))
789d1bf0
KS
2210
2211 ;; Check buf is non-nil.
2212 ((not buf) nil)
69beb26d 2213 ((= (length buf) 0) nil)
789d1bf0
KS
2214
2215 ;; View buffer if it exists
2216 ((get-buffer buf)
16f462c5 2217 (add-to-history 'buffer-name-history buf)
789d1bf0
KS
2218 (if (eq method 'insert)
2219 (progn
2220 (ido-record-command 'insert-buffer buf)
2d13e588
KS
2221 (push-mark
2222 (save-excursion
2223 (insert-buffer-substring (get-buffer buf))
2224 (point))))
789d1bf0
KS
2225 (ido-visit-buffer buf method t)))
2226
0523d117
JW
2227 ;; check for a virtual buffer reference
2228 ((and ido-use-virtual-buffers ido-virtual-buffers
2229 (setq filename (assoc buf ido-virtual-buffers)))
2230 (ido-visit-buffer (find-file-noselect (cdr filename)) method t))
2231
2232 ((and (eq ido-create-new-buffer 'prompt)
2233 (null require-match)
2234 (not (y-or-n-p (format "No buffer matching `%s', create one? " buf))))
2235 nil)
2236
789d1bf0 2237 ;; buffer doesn't exist
11c238b3
KS
2238 ((and (eq ido-create-new-buffer 'never)
2239 (null require-match))
a09e21bf 2240 (message "No buffer matching `%s'" buf))
789d1bf0
KS
2241
2242 ((and (eq ido-create-new-buffer 'prompt)
11c238b3 2243 (null require-match)
789d1bf0
KS
2244 (not (y-or-n-p (format "No buffer matching `%s', create one? " buf))))
2245 nil)
2246
2247 ;; create a new buffer
2248 (t
16f462c5 2249 (add-to-history 'buffer-name-history buf)
789d1bf0
KS
2250 (setq buf (get-buffer-create buf))
2251 (if (fboundp 'set-buffer-major-mode)
2252 (set-buffer-major-mode buf))
2253 (ido-visit-buffer buf method t))))))
2254
789d1bf0
KS
2255(defun ido-record-work-directory (&optional dir)
2256 (when (and (numberp ido-max-work-directory-list) (> ido-max-work-directory-list 0))
2257 (if (and (setq dir (or dir ido-current-directory)) (> (length dir) 0))
2258 (let ((items ido-work-directory-list-ignore-regexps)
2259 (case-fold-search nil))
2260 (while (and items dir)
2261 (if (string-match (car items) dir)
2262 (setq dir nil))
2263 (setq items (cdr items)))
2264 (if dir
2265 (setq ido-work-directory-list (cons dir (delete dir ido-work-directory-list))))))
2266 (if (> (length ido-work-directory-list) ido-max-work-directory-list)
2267 (setcdr (nthcdr (1- ido-max-work-directory-list) ido-work-directory-list) nil))))
2268
2269(defun ido-forget-work-directory ()
2270 (interactive)
2271 (when (and ido-current-directory ido-work-directory-list)
2272 (setq ido-work-directory-list (delete ido-current-directory ido-work-directory-list))
2273 (when ido-use-merged-list
2274 (ido-undo-merge-work-directory)
2275 (setq ido-exit 'refresh
2276 ido-try-merged-list t
2277 ido-use-merged-list t
2278 ido-text-init ido-text
2279 ido-rotate-temp t)
2280 (exit-minibuffer))))
71296446 2281
789d1bf0
KS
2282(defun ido-record-work-file (name)
2283 ;; Save NAME in ido-work-file-list
2284 (when (and (numberp ido-max-work-file-list) (> ido-max-work-file-list 0))
2285 (or
2286 (and ido-work-file-list (equal (car ido-work-file-list) name))
2287 (setq ido-work-file-list (cons name (delete name ido-work-file-list))))
2288 (if (> (length ido-work-file-list) ido-max-work-file-list)
2289 (setcdr (nthcdr (1- ido-max-work-file-list) ido-work-file-list) nil))))
2290
a70343bd
KS
2291(defun ido-expand-directory (dir)
2292 ;; Expand DIR or use DEFAULT-DIRECTORY if nil.
2293 ;; Add final slash to result in case it was missing from DEFAULT-DIRECTORY.
2294 (ido-final-slash (expand-file-name (or dir default-directory)) t))
2295
db9f395b 2296(defun ido-file-internal (method &optional fallback default prompt item initial switch-cmd)
789d1bf0 2297 ;; Internal function for ido-find-file and friends
310682e6
KS
2298 (unless item
2299 (setq item 'file))
94da3cf1
KS
2300 (let ((ido-current-directory (ido-expand-directory default))
2301 (ido-context-switch-command switch-cmd)
83a12f3a 2302 ido-directory-nonreadable ido-directory-too-big
94da3cf1
KS
2303 filename)
2304
2305 (if (or (not ido-mode) (ido-is-slow-ftp-host))
2306 (setq filename t
2307 ido-exit 'fallback)
2308 (setq ido-directory-nonreadable
2309 (ido-nonreadable-directory-p ido-current-directory)
2310 ido-directory-too-big
2311 (and (not ido-directory-nonreadable)
2312 (ido-directory-too-big-p ido-current-directory))))
2313
2314 (when (and (eq item 'file)
310682e6
KS
2315 (or ido-use-url-at-point ido-use-filename-at-point))
2316 (let (fn d)
2317 (require 'ffap)
fffa137c 2318 ;; Duplicate code from ffap-guesser as we want different behavior for files and URLs.
310682e6 2319 (cond
3729cc87
KS
2320 ((with-no-warnings
2321 (and ido-use-url-at-point
2322 ffap-url-regexp
2323 (ffap-fixup-url (or (ffap-url-at-point)
2324 (ffap-gopher-at-point)))))
310682e6
KS
2325 (setq ido-exit 'ffap
2326 filename t))
2327
2328 ((and ido-use-filename-at-point
004a00f4
DN
2329 (setq fn (with-no-warnings
2330 (if (eq ido-use-filename-at-point 'guess)
2331 (ffap-guesser)
2332 (ffap-string-at-point))))
d81aa76a 2333 (not (string-match "^http:/" fn))
b2d5f31a 2334 (setq d (file-name-directory (expand-file-name fn)))
310682e6
KS
2335 (file-directory-p d))
2336 (setq ido-current-directory d)
94da3cf1 2337 (setq initial (file-name-nondirectory fn))))))
310682e6
KS
2338
2339 (let (ido-saved-vc-hb
2340 (vc-handled-backends (and (boundp 'vc-handled-backends) vc-handled-backends))
789d1bf0
KS
2341 (ido-work-directory-index -1)
2342 (ido-work-file-index -1)
2343 (ido-find-literal nil))
2344
2345 (unless filename
310682e6 2346 (setq ido-saved-vc-hb vc-handled-backends)
d471b4fe
KS
2347 (let ((minibuffer-completing-file-name t))
2348 (setq filename (ido-read-internal item
2349 (or prompt "Find file: ")
033ecf78
KS
2350 'ido-file-history
2351 (and (eq method 'alt-file) buffer-file-name)
11c238b3 2352 (confirm-nonexistent-file-or-buffer) initial))))
789d1bf0
KS
2353
2354 ;; Choose the file name: either the text typed in, or the head
2355 ;; of the list of matches
2356
2357 (cond
2358 ((eq ido-exit 'fallback)
2359 ;; Need to guard setting of default-directory here, since
2360 ;; we don't want to change directory of current buffer.
2361 (let ((default-directory ido-current-directory)
2362 (read-file-name-function nil))
16f462c5
KS
2363 (setq this-command (or fallback 'find-file))
2364 (run-hook-with-args 'ido-before-fallback-functions this-command)
2365 (call-interactively this-command)))
789d1bf0 2366
db9f395b 2367 ((eq ido-exit 'switch-to-buffer)
7d046dbb
KS
2368 (ido-buffer-internal
2369 (if (memq method '(other-window other-frame)) method ido-default-buffer-method)
2370 nil nil nil ido-text))
789d1bf0 2371
db9f395b
KS
2372 ((eq ido-exit 'insert-buffer)
2373 (ido-buffer-internal 'insert 'insert-buffer "Insert buffer: " nil ido-text 'ido-enter-insert-file))
2374
789d1bf0
KS
2375 ((eq ido-exit 'dired)
2376 (dired (concat ido-current-directory (or ido-text ""))))
2377
310682e6
KS
2378 ((eq ido-exit 'ffap)
2379 (find-file-at-point))
2380
789d1bf0
KS
2381 ((eq method 'alt-file)
2382 (ido-record-work-file filename)
2383 (setq default-directory ido-current-directory)
2384 (ido-record-work-directory)
2385 (find-alternate-file filename))
2386
2387 ((memq method '(dired list-directory))
2388 (if (equal filename ".")
2389 (setq filename ""))
84f6c6d0
KS
2390 (let* ((dirname (ido-final-slash (concat ido-current-directory filename) t))
2391 (file (substring dirname 0 -1)))
789d1bf0 2392 (cond
84f6c6d0
KS
2393 ((file-directory-p dirname)
2394 (ido-record-command method dirname)
2395 (ido-record-work-directory dirname)
2396 (funcall method dirname))
789d1bf0
KS
2397 ((file-directory-p ido-current-directory)
2398 (cond
2399 ((file-exists-p file)
2400 (ido-record-command method ido-current-directory)
2401 (ido-record-work-directory)
2402 (funcall method ido-current-directory)
2403 (if (eq method 'dired)
3729cc87
KS
2404 (with-no-warnings
2405 (dired-goto-file (expand-file-name file)))))
789d1bf0 2406 ((string-match "[[*?]" filename)
84f6c6d0
KS
2407 (setq dirname (concat ido-current-directory filename))
2408 (ido-record-command method dirname)
789d1bf0 2409 (ido-record-work-directory)
84f6c6d0 2410 (funcall method dirname))
79164cf4 2411 ((y-or-n-p (format "Directory %s does not exist. Create it? " filename))
84f6c6d0
KS
2412 (ido-record-command method dirname)
2413 (ido-record-work-directory dirname)
2414 (make-directory-internal dirname)
2415 (funcall method dirname))
789d1bf0
KS
2416 (t
2417 ;; put make-directory command on history
84f6c6d0 2418 (ido-record-command 'make-directory dirname))))
789d1bf0
KS
2419 (t (error "No such directory")))))
2420
2421 ((eq method 'write)
2422 (ido-record-work-file filename)
2423 (setq default-directory ido-current-directory)
16f462c5
KS
2424 (setq filename (concat ido-current-directory filename))
2425 (ido-record-command 'write-file filename)
2426 (add-to-history 'file-name-history filename)
789d1bf0 2427 (ido-record-work-directory)
16f462c5 2428 (write-file filename))
789d1bf0
KS
2429
2430 ((eq method 'read-only)
2431 (ido-record-work-file filename)
2432 (setq filename (concat ido-current-directory filename))
2433 (ido-record-command fallback filename)
2434 (ido-record-work-directory)
b2d4c118 2435 (run-hook-with-args 'ido-before-fallback-functions fallback)
789d1bf0
KS
2436 (funcall fallback filename))
2437
2438 ((eq method 'insert)
2439 (ido-record-work-file filename)
2440 (setq filename (concat ido-current-directory filename))
71296446 2441 (ido-record-command
789d1bf0
KS
2442 (if ido-find-literal 'insert-file-literally 'insert-file)
2443 filename)
16f462c5 2444 (add-to-history 'file-name-history filename)
789d1bf0 2445 (ido-record-work-directory)
2d13e588
KS
2446 (insert-file-1 filename
2447 (if ido-find-literal
2448 #'insert-file-contents-literally
2449 #'insert-file-contents)))
789d1bf0
KS
2450
2451 (filename
2452 (ido-record-work-file filename)
2453 (setq filename (concat ido-current-directory filename))
2454 (ido-record-command 'find-file filename)
16f462c5 2455 (add-to-history 'file-name-history filename)
789d1bf0
KS
2456 (ido-record-work-directory)
2457 (ido-visit-buffer (find-file-noselect filename nil ido-find-literal) method))))))
2458
2459(defun ido-existing-item-p ()
2460 ;; Return non-nil if there is a matching item
2461 (not (null ido-matches)))
2462
2463;;; COMPLETION CODE
2464
2465(defun ido-set-common-completion ()
2466 ;; Find common completion of `ido-text' in `ido-matches'
2467 ;; The result is stored in `ido-common-match-string'
ccaa42ed
JB
2468 (let (val)
2469 (setq ido-common-match-string nil)
789d1bf0
KS
2470 (if (and ido-matches
2471 (not ido-enable-regexp) ;; testing
2472 (stringp ido-text)
2473 (> (length ido-text) 0))
2474 (if (setq val (ido-find-common-substring ido-matches ido-text))
2475 (setq ido-common-match-string val)))
2476 val))
2477
2478(defun ido-complete ()
2479 "Try and complete the current pattern amongst the file names."
2480 (interactive)
2481 (let (res)
71296446 2482 (cond
665ed61a
KS
2483 (ido-incomplete-regexp
2484 ;; Do nothing
2485 )
789d1bf0
KS
2486 ((and (memq ido-cur-item '(file dir))
2487 (string-match "[$]" ido-text))
2488 (let ((evar (substitute-in-file-name (concat ido-current-directory ido-text))))
2489 (if (not (file-exists-p (file-name-directory evar)))
337d2b66 2490 (message "Expansion generates non-existing directory name")
789d1bf0
KS
2491 (if (file-directory-p evar)
2492 (ido-set-current-directory evar)
2493 (let ((d (or (file-name-directory evar) "/"))
2494 (f (file-name-nondirectory evar)))
2495 (when (file-directory-p d)
2496 (ido-set-current-directory d)
2497 (setq ido-text-init f))))
2498 (setq ido-exit 'refresh)
2499 (exit-minibuffer))))
2500
cb65c373
KS
2501 (ido-directory-too-big
2502 (setq ido-directory-too-big nil)
2503 (setq ido-text-init ido-text)
2504 (setq ido-exit 'refresh)
2505 (exit-minibuffer))
2506
789d1bf0
KS
2507 ((not ido-matches)
2508 (when ido-completion-buffer
d1a0acac 2509 (call-interactively (setq this-command ido-cannot-complete-command))))
71296446 2510
bad111c2
KS
2511 ((and (= 1 (length ido-matches))
2512 (not (and ido-enable-tramp-completion
2513 (string-equal ido-current-directory "/")
10b19e88
KS
2514 (string-match ".[@:]\\'" (ido-name (car ido-matches)))))
2515 (not (ido-local-file-exists-p (ido-name (car ido-matches)))))
789d1bf0 2516 ;; only one choice, so select it.
d81aa76a
KS
2517 (if (not ido-confirm-unique-completion)
2518 (exit-minibuffer)
2519 (setq ido-rescan (not ido-enable-prefix))
2520 (delete-region (minibuffer-prompt-end) (point))
5a1b28a4 2521 (insert (ido-name (car ido-matches)))))
71296446 2522
789d1bf0
KS
2523 (t ;; else there could be some completions
2524 (setq res ido-common-match-string)
2525 (if (and (not (memq res '(t nil)))
2526 (not (equal res ido-text)))
2527 ;; found something to complete, so put it in the minibuffer.
2528 (progn
2529 ;; move exact match to front if not in prefix mode
2530 (setq ido-rescan (not ido-enable-prefix))
2531 (delete-region (minibuffer-prompt-end) (point))
2532 (insert res))
2533 ;; else nothing to complete
d1a0acac 2534 (call-interactively (setq this-command ido-cannot-complete-command))
789d1bf0
KS
2535 )))))
2536
030fa15b
KS
2537(defun ido-complete-space ()
2538 "Try completion unless inserting the space makes sense."
2539 (interactive)
2540 (if (and (stringp ido-common-match-string)
2541 (stringp ido-text)
2542 (cond
2543 ((> (length ido-common-match-string) (length ido-text))
2544 (= (aref ido-common-match-string (length ido-text)) ? ))
2545 (ido-matches
2546 (let (insert-space
2547 (re (concat (regexp-quote ido-text) " "))
2548 (comp ido-matches))
2549 (while comp
2550 (if (string-match re (ido-name (car comp)))
2551 (setq comp nil insert-space t)
2552 (setq comp (cdr comp))))
2553 insert-space))
2554 (t nil)))
2555 (insert " ")
2556 (ido-complete)))
2557
789d1bf0
KS
2558(defun ido-undo-merge-work-directory (&optional text try refresh)
2559 "Undo or redo last ido directory merge operation.
2560If no merge has yet taken place, toggle automatic merging option."
2561 (interactive)
2562 (cond
2563 (ido-pre-merge-state
2564 (ido-set-current-directory (nth 1 ido-pre-merge-state))
2565 (setq ido-text-init (or text (car ido-pre-merge-state))
2566 ido-cur-list (nth 2 ido-pre-merge-state)
2567 ido-ignored-list (nth 3 ido-pre-merge-state)
2568 ido-matches (nth 4 ido-pre-merge-state)
2569 ido-use-merged-list nil
2570 ido-try-merged-list try
2571 ido-keep-item-list (not refresh)
2572 ido-rescan nil
2573 ido-exit 'refresh
2574 ido-pre-merge-state nil)
2575 (exit-minibuffer))
2576 (text
2577 nil)
2578 (ido-try-merged-list
2579 (setq ido-try-merged-list nil))
2580 (ido-matches
2581 (setq ido-try-merged-list t))
2582 ((not ido-use-merged-list)
2583 (ido-merge-work-directories))))
71296446 2584
ae9d279d
KS
2585;;; Magic C-f
2586
a9dbdece 2587(defun ido-magic-forward-char (arg)
ae9d279d 2588 "Move forward in user input or perform magic action.
616e8e5f 2589If no user input is present, or at end of input, perform magic actions:
79164cf4
JB
2590C-x C-b ... C-f switch to `ido-find-file'.
2591C-x C-f ... C-f fallback to non-ido `find-file'.
2592C-x C-d ... C-f fallback to non-ido brief `dired'.
2593C-x d ... C-f fallback to non-ido `dired'."
a9dbdece 2594 (interactive "P")
ae9d279d 2595 (cond
a9dbdece
KS
2596 ((or arg (not (eobp)))
2597 (forward-char (min (prefix-numeric-value arg)
2598 (- (point-max) (point)))))
cc2691b7
KS
2599 ((memq ido-cur-item '(file dir))
2600 (ido-fallback-command))
2601 (ido-context-switch-command
2602 (call-interactively ido-context-switch-command))
2603 ((eq ido-cur-item 'buffer)
2604 (ido-enter-find-file))))
ae9d279d
KS
2605
2606;;; Magic C-b
2607
a9dbdece 2608(defun ido-magic-backward-char (arg)
ae9d279d 2609 "Move backward in user input or perform magic action.
cc2691b7 2610If no user input is present, or at start of input, perform magic actions:
a09e21bf
JB
2611C-x C-f C-b switch to `ido-switch-buffer'.
2612C-x C-d C-b switch to `ido-switch-buffer'.
2613C-x d C-b switch to `ido-switch-buffer'.
2614C-x C-b C-b fallback to non-ido `switch-to-buffer'."
a9dbdece 2615 (interactive "P")
ae9d279d 2616 (cond
a9dbdece
KS
2617 ((or arg (> (point) (minibuffer-prompt-end)))
2618 (forward-char
2619 (- (min (prefix-numeric-value arg)
2620 (- (point) (minibuffer-prompt-end))))))
155943b9
KS
2621 ((eq last-command this-command)
2622 (when (and (memq ido-cur-item '(file dir))
2623 (not (bobp)))
2624 (ido-push-dir))) ; else do nothing
ae9d279d 2625 ((eq ido-cur-item 'buffer)
cc2691b7
KS
2626 (ido-fallback-command))
2627 (ido-context-switch-command
2628 (call-interactively ido-context-switch-command))
2629 (t
2630 (ido-enter-switch-buffer))))
ae9d279d
KS
2631
2632;;; Magic C-d
2633
a9dbdece 2634(defun ido-magic-delete-char (arg)
ae9d279d
KS
2635 "Delete following char in user input or perform magic action.
2636If at end of user input, perform magic actions:
79164cf4 2637C-x C-f ... C-d enter `dired' on current directory."
a9dbdece 2638 (interactive "P")
ae9d279d 2639 (cond
a9dbdece
KS
2640 ((or arg (not (eobp)))
2641 (delete-char (min (prefix-numeric-value arg)
2642 (- (point-max) (point)))))
ae9d279d
KS
2643 (ido-context-switch-command
2644 nil)
2645 ((memq ido-cur-item '(file dir))
2646 (ido-enter-dired))))
2647
2648
789d1bf0
KS
2649;;; TOGGLE FUNCTIONS
2650
2651(defun ido-toggle-case ()
2652 "Toggle the value of `ido-case-fold'."
2653 (interactive)
2654 (setq ido-case-fold (not ido-case-fold))
2655 ;; ask for list to be regenerated.
2656 (setq ido-rescan t))
2657
2658(defun ido-toggle-regexp ()
2659 "Toggle the value of `ido-enable-regexp'."
2660 (interactive)
2661 (setq ido-enable-regexp (not ido-enable-regexp))
2662 ;; ask for list to be regenerated.
2663 (setq ido-rescan t))
2664
2665(defun ido-toggle-prefix ()
2666 "Toggle the value of `ido-enable-prefix'."
2667 (interactive)
2668 (setq ido-enable-prefix (not ido-enable-prefix))
2669 ;; ask for list to be regenerated.
2670 (setq ido-rescan t))
2671
2672(defun ido-toggle-ignore ()
2673 "Toggle ignoring files specified with `ido-ignore-files'."
2674 (interactive)
155943b9
KS
2675 (if (and (not (eobp)) (> (point) (minibuffer-prompt-end)))
2676 (goto-char (minibuffer-prompt-end))
2677 (if ido-directory-too-big
2678 (progn
2679 (message "Reading directory...")
2680 (setq ido-directory-too-big nil))
2681 (setq ido-process-ignore-lists (not ido-process-ignore-lists)))
2682 (setq ido-text-init ido-text)
2683 (setq ido-exit 'refresh)
2684 (exit-minibuffer)))
789d1bf0
KS
2685
2686(defun ido-toggle-vc ()
2687 "Disable version control for this file."
2688 (interactive)
2689 (if (and ido-mode (eq ido-cur-item 'file))
2690 (progn
310682e6
KS
2691 (setq vc-handled-backends
2692 (if vc-handled-backends nil ido-saved-vc-hb))
789d1bf0
KS
2693 (setq ido-text-init ido-text)
2694 (setq ido-exit 'keep)
2695 (exit-minibuffer))))
2696
2697(defun ido-toggle-literal ()
2698 "Toggle literal reading of this file."
2699 (interactive)
2700 (if (and ido-mode (eq ido-cur-item 'file))
2701 (progn
2702 (setq ido-find-literal (not ido-find-literal))
2703 (setq ido-text-init ido-text)
2704 (setq ido-exit 'keep)
2705 (exit-minibuffer))))
2706
2707(defun ido-reread-directory ()
2708 "Read current directory again.
2709May be useful if cached version is no longer valid, but directory
2710timestamp has not changed (e.g. with ftp or on Windows)."
2711 (interactive)
ff07e0ac 2712 (if (and ido-mode (memq ido-cur-item '(file dir)))
789d1bf0 2713 (progn
1b00bc64
KS
2714 (if (ido-is-unc-root)
2715 (setq ido-unc-hosts-cache t)
2716 (ido-remove-cached-dir ido-current-directory))
789d1bf0
KS
2717 (setq ido-text-init ido-text)
2718 (setq ido-rotate-temp t)
2719 (setq ido-exit 'refresh)
2720 (exit-minibuffer))))
2721
2722(defun ido-exit-minibuffer ()
2723 "Exit minibuffer, but make sure we have a match if one is needed."
2724 (interactive)
665ed61a 2725 (if (and (or (not ido-require-match)
11c238b3
KS
2726 (if (memq ido-require-match '(confirm confirm-after-completion))
2727 (if (or (eq ido-cur-item 'dir)
2728 (eq last-command this-command))
2729 t
2730 (setq ido-show-confirm-message t)
2731 nil))
665ed61a
KS
2732 (ido-existing-item-p))
2733 (not ido-incomplete-regexp))
3729cc87 2734 (exit-minibuffer)))
789d1bf0
KS
2735
2736(defun ido-select-text ()
2737 "Select the buffer or file named by the prompt.
2738If no buffer or file exactly matching the prompt exists, maybe create a new one."
2739 (interactive)
2740 (setq ido-exit 'takeprompt)
2741 (exit-minibuffer))
2742
2743(defun ido-fallback-command ()
2744 "Fallback to non-ido version of current command."
2745 (interactive)
4260eddd
KS
2746 (let ((i (length ido-text)))
2747 (while (> i 0)
2748 (push (aref ido-text (setq i (1- i))) unread-command-events)))
789d1bf0
KS
2749 (setq ido-exit 'fallback)
2750 (exit-minibuffer))
2751
2752(defun ido-enter-find-file ()
616e8e5f 2753 "Drop into `find-file' from buffer switching."
789d1bf0 2754 (interactive)
db9f395b 2755 (setq ido-exit 'find-file)
789d1bf0
KS
2756 (exit-minibuffer))
2757
2758(defun ido-enter-switch-buffer ()
616e8e5f 2759 "Drop into `ido-switch-buffer' from file switching."
789d1bf0 2760 (interactive)
db9f395b 2761 (setq ido-exit 'switch-to-buffer)
789d1bf0
KS
2762 (exit-minibuffer))
2763
2764(defun ido-enter-dired ()
a09e21bf 2765 "Drop into `dired' from file switching."
789d1bf0
KS
2766 (interactive)
2767 (setq ido-exit 'dired)
2768 (exit-minibuffer))
2769
db9f395b 2770(defun ido-enter-insert-buffer ()
a09e21bf 2771 "Drop into `insert-buffer' from insert file."
db9f395b
KS
2772 (interactive)
2773 (setq ido-exit 'insert-buffer)
2774 (exit-minibuffer))
2775
2776(defun ido-enter-insert-file ()
a09e21bf 2777 "Drop into `insert-file' from insert buffer."
db9f395b
KS
2778 (interactive)
2779 (setq ido-exit 'insert-file)
2780 (exit-minibuffer))
2781
789d1bf0
KS
2782
2783(defun ido-up-directory (&optional clear)
2784 "Go up one directory level."
2785 (interactive "P")
2786 (setq ido-text-init (if clear nil ido-text))
2787 (setq ido-exit 'updir)
2788 (setq ido-rotate-temp t)
2789 (exit-minibuffer))
2790
2791(defun ido-delete-backward-updir (count)
2792 "Delete char backwards, or at beginning of buffer, go up one level."
2793 (interactive "P")
2794 (cond
2795 ((= (minibuffer-prompt-end) (point))
2796 (if (not count)
2797 (ido-up-directory t)))
2798 ((and ido-pre-merge-state (string-equal (car ido-pre-merge-state) ido-text))
2799 (ido-undo-merge-work-directory (substring ido-text 0 -1) t t))
f0a73ccc
KS
2800 ((eq this-original-command 'viper-backward-char)
2801 (funcall this-original-command (prefix-numeric-value count)))
2802 ((eq this-original-command 'viper-del-backward-char-in-insert)
2803 (funcall this-original-command))
789d1bf0
KS
2804 (t
2805 (delete-backward-char (prefix-numeric-value count)))))
2806
2807(defun ido-delete-backward-word-updir (count)
2808 "Delete all chars backwards, or at beginning of buffer, go up one level."
2809 (interactive "P")
2810 (if (= (minibuffer-prompt-end) (point))
2811 (if (not count)
2812 (ido-up-directory t))
f0a73ccc
KS
2813 (if (eq this-original-command 'viper-delete-backward-word)
2814 (funcall this-original-command (prefix-numeric-value count))
2815 (backward-kill-word (prefix-numeric-value count)))))
789d1bf0
KS
2816
2817(defun ido-get-work-directory (&optional incr must-match)
2818 (let ((n (length ido-work-directory-list))
2819 (i ido-work-directory-index)
2820 (j 0)
2821 dir)
2822 (if (or (not ido-text) (= (length ido-text) 0))
2823 (setq must-match nil))
2824 (while (< j n)
2825 (setq i (+ i incr)
2826 j (1+ j))
2827 (if (> incr 0)
2828 (if (>= i n) (setq i 0))
2829 (if (< i 0) (setq i (1- n))))
2830 (setq dir (nth i ido-work-directory-list))
2831 (if (and dir
2832 (not (equal dir ido-current-directory))
2833 (file-directory-p dir)
2834 (or (not must-match)
cb65c373 2835 ;; TODO. check for nonreadable and too-big.
ec441ab5 2836 (ido-set-matches-1
789d1bf0 2837 (if (eq ido-cur-item 'file)
ec441ab5
KS
2838 (ido-make-file-list-1 dir)
2839 (ido-make-dir-list-1 dir)))))
789d1bf0
KS
2840 (setq j n)
2841 (setq dir nil)))
2842 (if dir
2843 (setq ido-work-directory-index i))
2844 dir))
2845
2846(defun ido-prev-work-directory ()
2847 "Change to next working directory in list."
2848 (interactive)
2849 (let ((dir (ido-get-work-directory 1 ido-work-directory-match-only)))
2850 (when dir
2851 (ido-set-current-directory dir)
2852 (setq ido-exit 'refresh)
2853 (setq ido-text-init ido-text)
2854 (setq ido-rotate-temp t)
2855 (exit-minibuffer))))
2856
2857(defun ido-next-work-directory ()
2858 "Change to previous working directory in list."
2859 (interactive)
2860 (let ((dir (ido-get-work-directory -1 ido-work-directory-match-only)))
2861 (when dir
2862 (ido-set-current-directory dir)
2863 (setq ido-exit 'refresh)
2864 (setq ido-text-init ido-text)
2865 (setq ido-rotate-temp t)
2866 (exit-minibuffer))))
2867
2868(defun ido-merge-work-directories ()
2869 "Search (and merge) work directories for files matching the current input string."
2870 (interactive)
2871 (setq ido-use-merged-list t ido-try-merged-list t)
2872 (setq ido-exit 'refresh)
2873 (setq ido-text-init ido-text)
2874 (setq ido-rotate-temp t)
2875 (exit-minibuffer))
2876
2877(defun ido-wide-find-file (&optional file)
2878 "Prompt for FILE to search for using find, starting from current directory."
2879 (interactive)
2880 (unless file
b0df3884
KS
2881 (let ((enable-recursive-minibuffers t))
2882 (setq file
3729cc87
KS
2883 (condition-case nil
2884 (read-string (concat "Wide find file: " ido-current-directory) ido-text)
2885 (quit "")))))
789d1bf0
KS
2886 (when (> (length file) 0)
2887 (setq ido-use-merged-list t ido-try-merged-list 'wide)
2888 (setq ido-exit 'refresh)
2889 (setq ido-text-init file)
2890 (setq ido-rotate-temp t)
2891 (exit-minibuffer)))
2892
2893(defun ido-wide-find-dir (&optional dir)
2894 "Prompt for DIR to search for using find, starting from current directory."
2895 (interactive)
2896 (unless dir
b0df3884
KS
2897 (let ((enable-recursive-minibuffers t))
2898 (setq dir
3729cc87
KS
2899 (condition-case nil
2900 (read-string (concat "Wide find directory: " ido-current-directory) ido-text)
2901 (quit "")))))
789d1bf0
KS
2902 (when (> (length dir) 0)
2903 (setq ido-use-merged-list t ido-try-merged-list 'wide)
2904 (setq ido-exit 'refresh)
2905 (setq ido-text-init (ido-final-slash dir t))
2906 (setq ido-rotate-temp t)
2907 (exit-minibuffer)))
2908
ae9d279d
KS
2909(defun ido-wide-find-dir-or-delete-dir (&optional dir)
2910 "Prompt for DIR to search for using find, starting from current directory.
2911If input stack is non-empty, delete current directory component."
2912 (interactive)
2913 (if ido-input-stack
2914 (ido-delete-backward-word-updir 1)
2915 (ido-wide-find-dir)))
2916
a3f4d4d4
KS
2917(defun ido-take-first-match ()
2918 "Use first matching item as input text."
2919 (interactive)
2920 (when ido-matches
5a1b28a4 2921 (setq ido-text-init (ido-name (car ido-matches)))
a3f4d4d4
KS
2922 (setq ido-exit 'refresh)
2923 (exit-minibuffer)))
2924
3729cc87
KS
2925(defun ido-push-dir ()
2926 "Move to previous directory in file name, push current input on stack."
2927 (interactive)
2928 (setq ido-exit 'push)
2929 (exit-minibuffer))
2930
a3f4d4d4
KS
2931(defun ido-push-dir-first ()
2932 "Move to previous directory in file name, push first match on stack."
2933 (interactive)
2934 (if ido-matches
5a1b28a4 2935 (setq ido-text (ido-name (car ido-matches))))
a3f4d4d4
KS
2936 (setq ido-exit 'push)
2937 (exit-minibuffer))
2938
3729cc87
KS
2939(defun ido-pop-dir (arg)
2940 "Pop directory from input stack back to input.
79164cf4 2941With \\[universal-argument], pop all elements."
3729cc87
KS
2942 (interactive "P")
2943 (when ido-input-stack
2944 (setq ido-exit (if arg 'pop-all 'pop))
2945 (exit-minibuffer)))
2946
2947(defun ido-wide-find-file-or-pop-dir (arg)
2948 (interactive "P")
2949 (if ido-input-stack
2950 (ido-pop-dir arg)
2951 (ido-wide-find-file)))
2952
789d1bf0
KS
2953(defun ido-make-directory (&optional dir)
2954 "Prompt for DIR to create in current directory."
2955 (interactive)
2956 (unless dir
b0df3884
KS
2957 (let ((enable-recursive-minibuffers t))
2958 (setq dir
2959 (read-string (concat "Make directory: " ido-current-directory) ido-text))))
789d1bf0
KS
2960 (when (> (length dir) 0)
2961 (setq dir (concat ido-current-directory dir))
2962 (unless (file-exists-p dir)
2963 (make-directory dir t)
2964 (ido-set-current-directory dir)
2965 (setq ido-exit 'refresh)
2966 (setq ido-text-init nil)
2967 (setq ido-rotate-temp t)
2968 (exit-minibuffer))))
2969
2970(defun ido-get-work-file (incr)
2971 (let ((n (length ido-work-file-list))
2972 (i (+ ido-work-file-index incr))
2973 name)
2974 (if (> incr 0)
2975 (if (>= i n) (setq i 0))
2976 (if (< i 0) (setq i (1- n))))
2977 (setq name (nth i ido-work-file-list))
2978 (setq ido-work-file-index i)
2979 name))
2980
2981(defun ido-prev-work-file ()
2982 "Change to next working file name in list."
2983 (interactive)
2984 (let ((name (ido-get-work-file 1)))
2985 (when name
2986 (setq ido-text-init name)
2987 (setq ido-exit 'refresh)
2988 (exit-minibuffer))))
2989
2990(defun ido-next-work-file ()
2991 "Change to previous working file name in list."
2992 (interactive)
2993 (let ((name (ido-get-work-file -1)))
2994 (when name
2995 (setq ido-text-init name)
2996 (setq ido-exit 'refresh)
2997 (exit-minibuffer))))
2998
2999(defun ido-copy-current-file-name (all)
3000 "Insert file name of current buffer.
3001If repeated, insert text from buffer instead."
3002 (interactive "P")
bac4dbd1
KS
3003 (let* ((bfname (or (buffer-file-name ido-entry-buffer)
3004 (buffer-name ido-entry-buffer)))
84f6c6d0 3005 (name (and bfname (file-name-nondirectory bfname))))
789d1bf0 3006 (when name
71296446
JB
3007 (setq ido-text-init
3008 (if (or all
2490c740 3009 (eq last-command this-command)
84f6c6d0 3010 (not (equal (file-name-directory bfname) ido-current-directory))
789d1bf0
KS
3011 (not (string-match "\\.[^.]*\\'" name)))
3012 name
3013 (substring name 0 (1+ (match-beginning 0)))))
3014 (setq ido-exit 'refresh
3015 ido-try-merged-list nil)
3016 (exit-minibuffer))))
71296446 3017
789d1bf0 3018(defun ido-copy-current-word (all)
362cdb61 3019 "Insert current word (file or directory name) from current buffer."
789d1bf0 3020 (interactive "P")
7fdbcd83 3021 (let ((word (with-current-buffer ido-entry-buffer
789d1bf0 3022 (let ((p (point)) start-line end-line start-name name)
1b5929b9
KS
3023 (if (and mark-active (/= p (mark)))
3024 (setq start-name (mark))
3025 (beginning-of-line)
3026 (setq start-line (point))
3027 (end-of-line)
3028 (setq end-line (point))
3029 (goto-char p)
3030 (if (re-search-backward "[^-_a-zA-Z0-9:./\\~@]" start-line 1)
3031 (forward-char 1))
3032 (setq start-name (point))
3033 (re-search-forward "[-_a-zA-Z0-9:./\\~@]*" end-line 1)
3034 (if (= start-name (point))
3035 (setq start-name nil)))
3036 (and start-name
3037 (buffer-substring-no-properties start-name (point)))))))
789d1bf0
KS
3038 (if (cond
3039 ((not word) nil)
3040 ((string-match "\\`[~/]" word)
3041 (setq ido-text-init word
3042 ido-try-merged-list nil
3043 ido-exit 'chdir))
3044 ((string-match "/" word)
3045 (setq ido-text-init (concat ido-current-directory word)
3046 ido-try-merged-list nil
3047 ido-exit 'chdir))
3048 (t
3049 (setq ido-text-init word
3050 ido-try-merged-list nil
3051 ido-exit 'refresh)))
3052 (exit-minibuffer))))
3053
71296446 3054(defun ido-next-match ()
789d1bf0
KS
3055 "Put first element of `ido-matches' at the end of the list."
3056 (interactive)
3057 (if ido-matches
3058 (let ((next (cadr ido-matches)))
3059 (setq ido-cur-list (ido-chop ido-cur-list next))
3060 (setq ido-rescan t)
3061 (setq ido-rotate t))))
3062
71296446 3063(defun ido-prev-match ()
789d1bf0
KS
3064 "Put last element of `ido-matches' at the front of the list."
3065 (interactive)
3066 (if ido-matches
3067 (let ((prev (car (last ido-matches))))
3068 (setq ido-cur-list (ido-chop ido-cur-list prev))
3069 (setq ido-rescan t)
3070 (setq ido-rotate t))))
3071
71296446 3072(defun ido-next-match-dir ()
789d1bf0
KS
3073 "Find next directory in match list.
3074If work directories have been merged, cycle through directories for
3075first matching file."
3076 (interactive)
3077 (if ido-use-merged-list
3078 (if ido-matches
3079 (let* ((elt (car ido-matches))
3080 (dirs (cdr elt)))
3081 (when (> (length dirs) 1)
3082 (setcdr elt (ido-chop dirs (cadr dirs))))
3083 (setq ido-rescan nil)))
3084 (let ((cnt (length ido-matches))
3085 (i 1))
3086 (while (and (< i cnt) (not (ido-final-slash (nth i ido-matches))))
3087 (setq i (1+ i)))
3088 (if (< i cnt)
3089 (setq ido-cur-list (ido-chop ido-cur-list (nth i ido-matches)))))))
3090
71296446 3091(defun ido-prev-match-dir ()
789d1bf0
KS
3092 "Find previous directory in match list.
3093If work directories have been merged, cycle through directories
3094for first matching file."
3095 (interactive)
3096 (if ido-use-merged-list
3097 (if ido-matches
3098 (let* ((elt (car ido-matches))
3099 (dirs (cdr elt)))
3100 (when (> (length dirs) 1)
3101 (setcdr elt (ido-chop dirs (car (last dirs)))))
3102 (setq ido-rescan nil)))
3103 (let* ((cnt (length ido-matches))
3104 (i (1- cnt)))
3105 (while (and (> i 0) (not (ido-final-slash (nth i ido-matches))))
3106 (setq i (1- i)))
3107 (if (> i 0)
3108 (setq ido-cur-list (ido-chop ido-cur-list (nth i ido-matches)))))))
3109
71296446 3110(defun ido-restrict-to-matches ()
08bfde76
KS
3111 "Set current item list to the currently matched items."
3112 (interactive)
3113 (when ido-matches
3114 (setq ido-cur-list ido-matches
3115 ido-text-init ""
3116 ido-rescan nil
3117 ido-exit 'keep)
3118 (exit-minibuffer)))
3119
789d1bf0
KS
3120(defun ido-chop (items elem)
3121 "Remove all elements before ELEM and put them at the end of ITEMS."
3122 (let ((ret nil)
3123 (next nil)
3124 (sofar nil))
3125 (while (not ret)
3126 (setq next (car items))
3127 (if (equal next elem)
3128 (setq ret (append items (nreverse sofar)))
3129 ;; else
3130 (progn
3131 (setq items (cdr items))
3132 (setq sofar (cons next sofar)))))
3133 ret))
3134
3135(defun ido-name (item)
3136 ;; Return file name for current item, whether in a normal list
3137 ;; or a merged work directory list.
3138 (if (consp item) (car item) item))
3139
3140
3141;;; CREATE LIST OF ALL CURRENT FILES
3142
3143(defun ido-all-completions ()
3144 ;; Return unsorted list of all competions.
cb65c373
KS
3145 (let ((ido-process-ignore-lists nil)
3146 (ido-directory-too-big nil))
789d1bf0
KS
3147 (cond
3148 ((eq ido-cur-item 'file)
ec441ab5 3149 (ido-make-file-list-1 ido-current-directory))
789d1bf0 3150 ((eq ido-cur-item 'dir)
ec441ab5 3151 (ido-make-dir-list-1 ido-current-directory))
789d1bf0 3152 ((eq ido-cur-item 'buffer)
ec441ab5 3153 (ido-make-buffer-list-1))
db9f395b
KS
3154 ((eq ido-cur-item 'list)
3155 ido-choice-list)
789d1bf0
KS
3156 (t nil))))
3157
3158
1de0ae85
KS
3159;; File list sorting
3160
3161(defun ido-file-lessp (a b)
3162 ;; Simple compare two file names.
3163 (string-lessp (ido-no-final-slash a) (ido-no-final-slash b)))
3164
3165
3166(defun ido-file-extension-lessp (a b)
3167 ;; Compare file names according to ido-file-extensions-order list.
3168 (let ((n (compare-strings a 0 nil b 0 nil nil))
3169 lessp p)
3170 (if (eq n t)
3171 nil
3172 (if (< n 0)
3173 (setq n (1- (- n))
3174 p a a b b p
3175 lessp t)
3176 (setq n (1- n)))
3177 (cond
3178 ((= n 0)
3179 lessp)
3180 ((= (aref a n) ?.)
3181 (ido-file-extension-aux a b n lessp))
3182 (t
3183 (while (and (> n 2) (/= (aref a n) ?.))
3184 (setq n (1- n)))
3185 (if (> n 1)
3186 (ido-file-extension-aux a b n lessp)
3187 lessp))))))
3188
3189(defun ido-file-extension-aux (a b n lessp)
3190 (let ((oa (ido-file-extension-order a n))
3191 (ob (ido-file-extension-order b n)))
3192 (cond
1de0ae85 3193 ((and oa ob)
76a63a6e
KS
3194 (cond
3195 ((= oa ob)
3196 lessp)
3197 (lessp
3198 (> oa ob))
3199 (t
3200 (< oa ob))))
1de0ae85
KS
3201 (oa
3202 (not lessp))
3203 (ob
3204 lessp)
3205 (t
3206 lessp))))
3207
3208(defun ido-file-extension-order (s n)
3209 (let ((l ido-file-extensions-order)
3210 (i 0) o do)
3211 (while l
3212 (cond
3213 ((eq (car l) t)
3214 (setq do i
3215 l (cdr l)))
3216 ((eq (compare-strings s n nil (car l) 0 nil nil) t)
3217 (setq o i
3218 l nil))
3219 (t
3220 (setq l (cdr l))))
3221 (setq i (1+ i)))
3222 (or o do)))
3223
789d1bf0
KS
3224
3225(defun ido-sort-merged-list (items promote)
3226 ;; Input is list of ("file" . "dir") cons cells.
3227 ;; Output is sorted list of ("file "dir" ...) lists
3228 (let ((l (sort items (lambda (a b) (string-lessp (car b) (car a)))))
3229 res a cur dirs)
3230 (while l
3231 (setq a (car l)
3232 l (cdr l))
3233 (if (and res (string-equal (car (car res)) (car a)))
3234 (progn
3235 (setcdr (car (if cur (cdr res) res)) (cons (cdr a) (cdr (car res))))
3236 (if (and promote (string-equal ido-current-directory (cdr a)))
3237 (setq cur t)))
3238 (setq res (cons (list (car a) (cdr a)) res)
3239 cur nil)))
3240 res))
3241
3242(defun ido-wide-find-dirs-or-files (dir file &optional prefix finddir)
3243 ;; As ido-run-find-command, but returns a list of cons pairs ("file" . "dir")
71296446
JB
3244 (let ((filenames
3245 (split-string
789d1bf0 3246 (shell-command-to-string
ec579201
KS
3247 (concat "find "
3248 (shell-quote-argument dir)
3249 " -name "
3250 (shell-quote-argument
3251 (concat (if prefix "" "*") file "*"))
3252 " -type " (if finddir "d" "f") " -print"))))
84f6c6d0 3253 filename d f
789d1bf0 3254 res)
84f6c6d0
KS
3255 (while filenames
3256 (setq filename (car filenames)
3257 filenames (cdr filenames))
3258 (if (and (string-match "^/" filename)
3259 (file-exists-p filename))
3260 (setq d (file-name-directory filename)
3261 f (file-name-nondirectory filename)
789d1bf0
KS
3262 res (cons (cons (if finddir (ido-final-slash f t) f) d) res))))
3263 res))
3264
3265(defun ido-flatten-merged-list (items)
362cdb61 3266 ;; Create a list of directory names based on a merged directory list.
789d1bf0
KS
3267 (let (res)
3268 (while items
3269 (let* ((item (car items))
3270 (file (car item))
3271 (dirs (cdr item)))
3272 (while dirs
3273 (setq res (cons (concat (car dirs) file) res)
3274 dirs (cdr dirs))))
3275 (setq items (cdr items)))
3276 res))
3277
ec441ab5
KS
3278
3279(defun ido-make-merged-file-list-1 (text auto wide)
789d1bf0 3280 (let (res)
ec441ab5
KS
3281 (if (and (ido-final-slash text) ido-dir-file-cache)
3282 (if wide
3283 (setq res (ido-wide-find-dirs-or-files
3284 ido-current-directory (substring text 0 -1) ido-enable-prefix t))
3285 ;; Use list of cached directories
3286 (let ((re (concat (regexp-quote (substring text 0 -1)) "[^/:]*/\\'"))
3287 (dirs ido-dir-file-cache)
3288 dir b d f)
3289 (if nil ;; simple
3290 (while dirs
3291 (setq dir (car (car dirs))
3292 dirs (cdr dirs))
3293 (when (and (string-match re dir)
3294 (not (ido-ignore-item-p dir ido-ignore-directories-merge))
3295 (file-directory-p dir))
3296 (setq b (substring dir 0 -1)
3297 f (concat (file-name-nondirectory b) "/")
3298 d (file-name-directory b)
3299 res (cons (cons f d) res))))
789d1bf0
KS
3300 (while dirs
3301 (setq dir (car dirs)
ec441ab5 3302 d (car dir)
789d1bf0 3303 dirs (cdr dirs))
ec441ab5
KS
3304 (when (not (ido-ignore-item-p d ido-ignore-directories-merge))
3305 (setq dir (cdr (cdr dir)))
3306 (while dir
3307 (setq f (car dir)
3308 dir (cdr dir))
3309 (if (and (string-match re f)
3310 (not (ido-ignore-item-p f ido-ignore-directories)))
3311 (setq res (cons (cons f d) res)))))
789d1bf0
KS
3312 (if (and auto (input-pending-p))
3313 (setq dirs nil
3314 res t))))))
ec441ab5
KS
3315 (if wide
3316 (setq res (ido-wide-find-dirs-or-files
3317 ido-current-directory text ido-enable-prefix nil))
3318 (let ((ido-text text)
3319 (dirs ido-work-directory-list)
3320 (must-match (and text (> (length text) 0)))
3321 dir fl)
3322 (if (and auto (not (member ido-current-directory dirs)))
3323 (setq dirs (cons ido-current-directory dirs)))
3324 (while dirs
3325 (setq dir (car dirs)
3326 dirs (cdr dirs))
3327 (when (and dir (stringp dir)
3328 (or ido-merge-ftp-work-directories
3329 (not (ido-is-ftp-directory dir)))
3330 (file-directory-p dir)
3331 ;; TODO. check for nonreadable and too-big.
3332 (setq fl (if (eq ido-cur-item 'file)
3333 (ido-make-file-list-1 dir t)
3334 (ido-make-dir-list-1 dir t))))
3335 (if must-match
3336 (setq fl (ido-set-matches-1 fl)))
3337 (if fl
3338 (setq res (nconc fl res))))
3339 (if (and auto (input-pending-p))
3340 (setq dirs nil
3341 res t))))))
3342 res))
3343
3344(defun ido-make-merged-file-list (text auto wide)
3345 (let (res)
3346 (message "Searching for `%s'...." text)
3347 (condition-case nil
edc42f56
KS
3348 (if (eq t (setq res
3349 (while-no-input
3350 (ido-make-merged-file-list-1 text auto wide))))
3351 (setq res 'input-pending-p))
ec441ab5
KS
3352 (quit
3353 (setq res t
3354 ido-try-merged-list nil
3355 ido-use-merged-list nil)))
3356 (when (and res (listp res))
3357 (setq res (ido-sort-merged-list res auto)))
9a08196a 3358 (when (and (or ido-rotate-temp ido-rotate-file-list-default)
e20b3173 3359 (listp res)
9a08196a
KS
3360 (> (length text) 0))
3361 (let ((elt (assoc text res)))
4e85a733 3362 (when (and elt (not (eq elt (car res))))
9a08196a
KS
3363 (setq res (delq elt res))
3364 (setq res (cons elt res)))))
789d1bf0
KS
3365 (message nil)
3366 res))
3367
ec441ab5 3368(defun ido-make-buffer-list-1 (&optional frame visible)
789d1bf0 3369 ;; Return list of non-ignored buffer names
71296446 3370 (delq nil
789d1bf0
KS
3371 (mapcar
3372 (lambda (x)
3373 (let ((name (buffer-name x)))
69beb26d 3374 (if (not (or (ido-ignore-item-p name ido-ignore-buffers) (member name visible)))
789d1bf0
KS
3375 name)))
3376 (buffer-list frame))))
3377
3378(defun ido-make-buffer-list (default)
3379 ;; Return the current list of buffers.
3380 ;; Currently visible buffers are put at the end of the list.
616e8e5f 3381 ;; The hook `ido-make-buffer-list-hook' is run after the list has been
789d1bf0
KS
3382 ;; created to allow the user to further modify the order of the buffer names
3383 ;; in this list. If DEFAULT is non-nil, and corresponds to an existing buffer,
3384 ;; it is put to the start of the list.
3385 (let* ((ido-current-buffers (ido-get-buffers-in-frames 'current))
ec441ab5 3386 (ido-temp-list (ido-make-buffer-list-1 (selected-frame) ido-current-buffers)))
789d1bf0
KS
3387 (if ido-temp-list
3388 (nconc ido-temp-list ido-current-buffers)
3389 (setq ido-temp-list ido-current-buffers))
9caf8a8f
JB
3390 (when (and default (buffer-live-p (get-buffer default)))
3391 (setq ido-temp-list
3392 (cons default (delete default ido-temp-list))))
0523d117
JW
3393 (if ido-use-virtual-buffers
3394 (ido-add-virtual-buffers-to-list))
789d1bf0
KS
3395 (run-hooks 'ido-make-buffer-list-hook)
3396 ido-temp-list))
3397
0523d117
JW
3398(defun ido-add-virtual-buffers-to-list ()
3399 "Add recently visited files, and bookmark files, to the buffer list.
3400This is to make them appear as if they were \"virtual buffers\"."
3401 ;; If no buffers matched, and virtual buffers are being used, then
3402 ;; consult the list of past visited files, to see if we can find
3403 ;; the file which the user might thought was still open.
9caf8a8f 3404 (unless recentf-mode (recentf-mode 1))
0523d117 3405 (setq ido-virtual-buffers nil)
9caf8a8f
JB
3406 (let (name)
3407 (dolist (head recentf-list)
3408 (and (setq name (file-name-nondirectory head))
3409 (null (get-file-buffer head))
3410 (not (assoc name ido-virtual-buffers))
3411 (not (ido-ignore-item-p name ido-ignore-buffers))
3412 ;;(file-exists-p head)
3413 (push (cons name head) ido-virtual-buffers))))
0523d117
JW
3414 (when ido-virtual-buffers
3415 (if ido-use-faces
3416 (dolist (comp ido-virtual-buffers)
3417 (put-text-property 0 (length (car comp))
3418 'face 'ido-virtual
3419 (car comp))))
3420 (setq ido-temp-list
3421 (nconc ido-temp-list
3422 (nreverse (mapcar #'car ido-virtual-buffers))))))
3423
db9f395b
KS
3424(defun ido-make-choice-list (default)
3425 ;; Return the current list of choices.
3426 ;; If DEFAULT is non-nil, and corresponds to an element of choices,
3427 ;; it is put to the start of the list.
3428 (let ((ido-temp-list ido-choice-list))
3429 (if default
3430 (progn
3431 (setq ido-temp-list
3432 (delete default ido-temp-list))
3433 (setq ido-temp-list
3434 (cons default ido-temp-list))))
3435 ; (run-hooks 'ido-make-choice-list-hook)
3436 ido-temp-list))
3437
789d1bf0
KS
3438(defun ido-to-end (items)
3439 ;; Move the elements from ITEMS to the end of `ido-temp-list'
db99576a 3440 (mapc
71296446 3441 (lambda (elem)
789d1bf0
KS
3442 (setq ido-temp-list (delq elem ido-temp-list)))
3443 items)
3444 (if ido-temp-list
3445 (nconc ido-temp-list items)
3446 (setq ido-temp-list items)))
3447
2c52d7a3 3448(declare-function tramp-tramp-file-p "tramp" (name))
004a00f4 3449
ec441ab5 3450(defun ido-file-name-all-completions-1 (dir)
a70343bd 3451 (cond
866f2239 3452 ((ido-nonreadable-directory-p dir) '())
cb65c373
KS
3453 ;; do not check (ido-directory-too-big-p dir) here.
3454 ;; Caller must have done that if necessary.
c577a4d2 3455
a70343bd 3456 ((and ido-enable-tramp-completion
d9e43b70 3457 (or (fboundp 'tramp-completion-mode-p)
c577a4d2
KS
3458 (require 'tramp nil t))
3459 (string-match "\\`/[^/]+[:@]\\'" dir))
3460 ;; Strip method:user@host: part of tramp completions.
3461 ;; Tramp completions do not include leading slash.
d9e43b70
MA
3462 (let* ((len (1- (length dir)))
3463 (tramp-completion-mode t)
3464 (compl
3465 (or (file-name-all-completions "" dir)
3466 ;; work around bug in ange-ftp.
3467 ;; /ftp:user@host: => nil
3468 ;; /ftp:user@host:./ => ok
3469 (and
3470 (not (string= "/ftp:" dir))
3471 (tramp-tramp-file-p dir)
3472 (fboundp 'tramp-ftp-file-name-p)
3473 (funcall 'tramp-ftp-file-name-p dir)
3474 (string-match ":\\'" dir)
3475 (file-name-all-completions "" (concat dir "./"))))))
c577a4d2
KS
3476 (if (and compl
3477 (> (length (car compl)) len)
3478 (string= (substring (car compl) 0 len) (substring dir 1)))
a70343bd
KS
3479 (mapcar (lambda (c) (substring c len)) compl)
3480 compl)))
3481 (t
3482 (file-name-all-completions "" dir))))
bad111c2 3483
789d1bf0
KS
3484(defun ido-file-name-all-completions (dir)
3485 ;; Return name of all files in DIR
3486 ;; Uses and updates ido-dir-file-cache
dfebc0ae
KS
3487 (cond
3488 ((ido-is-unc-root dir)
3489 (mapcar
3490 (lambda (host)
3491 (if (string-match "/\\'" host) host (concat host "/")))
4c2ee078 3492 (ido-unc-hosts t)))
dfebc0ae
KS
3493 ((and (numberp ido-max-dir-file-cache) (> ido-max-dir-file-cache 0)
3494 (stringp dir) (> (length dir) 0)
3495 (ido-may-cache-directory dir))
3496 (let* ((cached (assoc dir ido-dir-file-cache))
71296446 3497 (ctime (nth 1 cached))
789d1bf0 3498 (ftp (ido-is-ftp-directory dir))
dfebc0ae
KS
3499 (unc (ido-is-unc-host dir))
3500 (attr (if (or ftp unc) nil (file-attributes dir)))
789d1bf0
KS
3501 (mtime (nth 5 attr))
3502 valid)
3503 (when cached ; should we use the cached entry ?
dfebc0ae
KS
3504 (cond
3505 (ftp
3506 (setq valid (and (eq (car ctime) 'ftp)
3507 (ido-cache-ftp-valid (cdr ctime)))))
3508 (unc
3509 (setq valid (and (eq (car ctime) 'unc)
3510 (ido-cache-unc-valid (cdr ctime)))))
3511 (t
789d1bf0
KS
3512 (if attr
3513 (setq valid (and (= (car ctime) (car mtime))
dfebc0ae
KS
3514 (= (car (cdr ctime)) (car (cdr mtime))))))))
3515 (unless valid
3516 (setq ido-dir-file-cache (delq cached ido-dir-file-cache)
3517 cached nil)))
789d1bf0 3518 (unless cached
dfebc0ae
KS
3519 (cond
3520 (unc
3521 (setq mtime (cons 'unc (ido-time-stamp))))
3522 ((and ftp (file-readable-p dir))
3523 (setq mtime (cons 'ftp (ido-time-stamp)))))
789d1bf0 3524 (if mtime
ec441ab5 3525 (setq cached (cons dir (cons mtime (ido-file-name-all-completions-1 dir)))
789d1bf0
KS
3526 ido-dir-file-cache (cons cached ido-dir-file-cache)))
3527 (if (> (length ido-dir-file-cache) ido-max-dir-file-cache)
3528 (setcdr (nthcdr (1- ido-max-dir-file-cache) ido-dir-file-cache) nil)))
3529 (and cached
dfebc0ae
KS
3530 (cdr (cdr cached)))))
3531 (t
3532 (ido-file-name-all-completions-1 dir))))
789d1bf0
KS
3533
3534(defun ido-remove-cached-dir (dir)
3535 ;; Remove dir from ido-dir-file-cache
3536 (if (and ido-dir-file-cache
3537 (stringp dir) (> (length dir) 0))
3538 (let ((cached (assoc dir ido-dir-file-cache)))
3539 (if cached
3540 (setq ido-dir-file-cache (delq cached ido-dir-file-cache))))))
3541
3542
ec441ab5 3543(defun ido-make-file-list-1 (dir &optional merged)
789d1bf0
KS
3544 ;; Return list of non-ignored files in DIR
3545 ;; If MERGED is non-nil, each file is cons'ed with DIR
dfebc0ae
KS
3546 (and (or (ido-is-tramp-root dir) (ido-is-unc-root dir)
3547 (file-directory-p dir))
71296446 3548 (delq nil
789d1bf0
KS
3549 (mapcar
3550 (lambda (name)
3551 (if (not (ido-ignore-item-p name ido-ignore-files t))
3552 (if merged (cons name dir) name)))
3553 (ido-file-name-all-completions dir)))))
3554
3555(defun ido-make-file-list (default)
3556 ;; Return the current list of files.
3557 ;; Currently visible files are put at the end of the list.
71296446 3558 ;; The hook `ido-make-file-list-hook' is run after the list has been
789d1bf0
KS
3559 ;; created to allow the user to further modify the order of the file names
3560 ;; in this list.
ec441ab5 3561 (let ((ido-temp-list (ido-make-file-list-1 ido-current-directory)))
1de0ae85
KS
3562 (setq ido-temp-list (sort ido-temp-list
3563 (if ido-file-extensions-order
3564 #'ido-file-extension-lessp
3565 #'ido-file-lessp)))
c577a4d2
KS
3566 (unless (ido-is-tramp-root ido-current-directory)
3567 (let ((default-directory ido-current-directory))
3568 (ido-to-end ;; move ftp hosts and visited files to end
3569 (delq nil (mapcar
10b19e88
KS
3570 (lambda (x) (if (or (and (string-match ".:\\'" x)
3571 (not (ido-local-file-exists-p x)))
c577a4d2 3572 (and (not (ido-final-slash x))
10b19e88
KS
3573 (let (file-name-handler-alist)
3574 (get-file-buffer x)))) x))
c577a4d2 3575 ido-temp-list)))))
789d1bf0 3576 (ido-to-end ;; move . files to end
71296446 3577 (delq nil (mapcar
789d1bf0
KS
3578 (lambda (x) (if (string-equal (substring x 0 1) ".") x))
3579 ido-temp-list)))
3580 (if (and default (member default ido-temp-list))
3581 (if (or ido-rotate-temp ido-rotate-file-list-default)
3582 (unless (equal default (car ido-temp-list))
3583 (let ((l ido-temp-list) k)
3584 (while (and l (cdr l) (not (equal default (car (cdr l)))))
3585 (setq l (cdr l)))
3586 (setq k (cdr l))
3587 (setcdr l nil)
3588 (nconc k ido-temp-list)
3589 (setq ido-temp-list k)))
71296446 3590 (setq ido-temp-list
789d1bf0 3591 (delete default ido-temp-list))
71296446 3592 (setq ido-temp-list
789d1bf0
KS
3593 (cons default ido-temp-list))))
3594 (when ido-show-dot-for-dired
3595 (setq ido-temp-list (delete "." ido-temp-list))
3596 (setq ido-temp-list (cons "." ido-temp-list)))
3597 (run-hooks 'ido-make-file-list-hook)
3598 ido-temp-list))
3599
ec441ab5 3600(defun ido-make-dir-list-1 (dir &optional merged)
789d1bf0
KS
3601 ;; Return list of non-ignored subdirs in DIR
3602 ;; If MERGED is non-nil, each subdir is cons'ed with DIR
bad111c2 3603 (and (or (ido-is-tramp-root dir) (file-directory-p dir))
71296446 3604 (delq nil
789d1bf0
KS
3605 (mapcar
3606 (lambda (name)
3607 (and (ido-final-slash name) (not (ido-ignore-item-p name ido-ignore-directories))
3608 (if merged (cons name dir) name)))
3609 (ido-file-name-all-completions dir)))))
3610
3611(defun ido-make-dir-list (default)
3612 ;; Return the current list of directories.
71296446 3613 ;; The hook `ido-make-dir-list-hook' is run after the list has been
789d1bf0
KS
3614 ;; created to allow the user to further modify the order of the
3615 ;; directory names in this list.
ec441ab5 3616 (let ((ido-temp-list (ido-make-dir-list-1 ido-current-directory)))
1de0ae85 3617 (setq ido-temp-list (sort ido-temp-list #'ido-file-lessp))
789d1bf0 3618 (ido-to-end ;; move . files to end
71296446 3619 (delq nil (mapcar
789d1bf0
KS
3620 (lambda (x) (if (string-equal (substring x 0 1) ".") x))
3621 ido-temp-list)))
3622 (if (and default (member default ido-temp-list))
3623 (if (or ido-rotate-temp ido-rotate-file-list-default)
3624 (unless (equal default (car ido-temp-list))
3625 (let ((l ido-temp-list) k)
3626 (while (and l (cdr l) (not (equal default (car (cdr l)))))
3627 (setq l (cdr l)))
3628 (setq k (cdr l))
3629 (setcdr l nil)
3630 (nconc k ido-temp-list)
3631 (setq ido-temp-list k)))
71296446 3632 (setq ido-temp-list
789d1bf0 3633 (delete default ido-temp-list))
71296446 3634 (setq ido-temp-list
789d1bf0
KS
3635 (cons default ido-temp-list))))
3636 (setq ido-temp-list (delete "." ido-temp-list))
3729cc87
KS
3637 (unless ido-input-stack
3638 (setq ido-temp-list (cons "." ido-temp-list)))
789d1bf0
KS
3639 (run-hooks 'ido-make-dir-list-hook)
3640 ido-temp-list))
3641
3642;; List of the files visible in the current frame.
3643(defvar ido-bufs-in-frame)
3644
3645(defun ido-get-buffers-in-frames (&optional current)
3646 ;; Return the list of buffers that are visible in the current frame.
3647 ;; If optional argument `current' is given, restrict searching to the
3648 ;; current frame, rather than all frames, regardless of value of
3649 ;; `ido-all-frames'.
3650 (let ((ido-bufs-in-frame nil))
3651 (walk-windows 'ido-get-bufname nil
71296446 3652 (if current
789d1bf0
KS
3653 nil
3654 ido-all-frames))
3655 ido-bufs-in-frame))
3656
3657(defun ido-get-bufname (win)
3658 ;; Used by `ido-get-buffers-in-frames' to walk through all windows
3659 (let ((buf (buffer-name (window-buffer win))))
69beb26d 3660 (unless (or (member buf ido-bufs-in-frame)
2acfb954 3661 (minibufferp buf)
69beb26d
KS
3662 (member buf ido-ignore-item-temp-list))
3663 ;; Only add buf if it is not already in list.
3664 ;; This prevents same buf in two different windows being
3665 ;; put into the list twice.
3666 (setq ido-bufs-in-frame
3667 (cons buf ido-bufs-in-frame)))))
789d1bf0
KS
3668
3669;;; FIND MATCHING ITEMS
3670
ec441ab5 3671(defun ido-set-matches-1 (items &optional do-full)
789d1bf0
KS
3672 ;; Return list of matches in items
3673 (let* ((case-fold-search ido-case-fold)
bad111c2
KS
3674 (slash (and (not ido-enable-prefix) (ido-final-slash ido-text)))
3675 (text (if slash (substring ido-text 0 -1) ido-text))
5444f278
KS
3676 (rex0 (if ido-enable-regexp text (regexp-quote text)))
3677 (rexq (concat rex0 (if slash ".*/" "")))
789d1bf0 3678 (re (if ido-enable-prefix (concat "\\`" rexq) rexq))
5444f278
KS
3679 (full-re (and do-full (not ido-enable-regexp) (not (string-match "\$\\'" rex0))
3680 (concat "\\`" rex0 (if slash "/" "") "\\'")))
3681 (suffix-re (and do-full slash
3682 (not ido-enable-regexp) (not (string-match "\$\\'" rex0))
3683 (concat rex0 "/\\'")))
789d1bf0
KS
3684 (prefix-re (and full-re (not ido-enable-prefix)
3685 (concat "\\`" rexq)))
6d8b6cbd
KS
3686 (non-prefix-dot (or (not ido-enable-dot-prefix)
3687 (not ido-process-ignore-lists)
3688 ido-enable-prefix
3689 (= (length ido-text) 0)))
5444f278 3690 full-matches suffix-matches prefix-matches matches)
665ed61a
KS
3691 (setq ido-incomplete-regexp nil)
3692 (condition-case error
db99576a 3693 (mapc
665ed61a
KS
3694 (lambda (item)
3695 (let ((name (ido-name item)))
5444f278
KS
3696 (if (and (or non-prefix-dot
3697 (if (= (aref ido-text 0) ?.)
3698 (= (aref name 0) ?.)
3699 (/= (aref name 0) ?.)))
3700 (string-match re name))
3701 (cond
39449da0 3702 ((and (eq ido-cur-item 'buffer)
3d37467b
KS
3703 (or (not (stringp ido-default-item))
3704 (not (string= name ido-default-item)))
39449da0
KS
3705 (string= name (buffer-name ido-entry-buffer)))
3706 (setq matches (cons item matches)))
5444f278
KS
3707 ((and full-re (string-match full-re name))
3708 (setq full-matches (cons item full-matches)))
3709 ((and suffix-re (string-match suffix-re name))
3710 (setq suffix-matches (cons item suffix-matches)))
3711 ((and prefix-re (string-match prefix-re name))
3712 (setq prefix-matches (cons item prefix-matches)))
3713 (t (setq matches (cons item matches))))))
3714 t)
665ed61a
KS
3715 items)
3716 (invalid-regexp
3717 (setq ido-incomplete-regexp t
3718 ;; Consider the invalid regexp message internally as a
3719 ;; special-case single match, and handle appropriately
3720 ;; elsewhere.
3721 matches (cdr error))))
5444f278
KS
3722 (when prefix-matches
3723 (ido-trace "prefix match" prefix-matches)
9940702b 3724 ;; Bug#2042.
5444f278
KS
3725 (setq matches (nconc prefix-matches matches)))
3726 (when suffix-matches
3727 (ido-trace "suffix match" (list text suffix-re suffix-matches))
3728 (setq matches (nconc suffix-matches matches)))
3729 (when full-matches
3730 (ido-trace "full match" (list text full-re full-matches))
3731 (setq matches (nconc full-matches matches)))
789d1bf0
KS
3732 (when (and (null matches)
3733 ido-enable-flex-matching
3734 (> (length ido-text) 1)
3735 (not ido-enable-regexp))
9066a4d0 3736 (setq re (mapconcat #'regexp-quote (split-string ido-text "") ".*"))
789d1bf0
KS
3737 (if ido-enable-prefix
3738 (setq re (concat "\\`" re)))
db99576a 3739 (mapc
789d1bf0
KS
3740 (lambda (item)
3741 (let ((name (ido-name item)))
3742 (if (string-match re name)
3743 (setq matches (cons item matches)))))
3744 items))
3745 matches))
71296446 3746
789d1bf0
KS
3747
3748(defun ido-set-matches ()
3749 ;; Set `ido-matches' to the list of items matching prompt
3750 (when ido-rescan
ec441ab5 3751 (setq ido-matches (ido-set-matches-1 (reverse ido-cur-list) (not ido-rotate))
789d1bf0 3752 ido-rotate nil)))
71296446 3753
789d1bf0
KS
3754(defun ido-ignore-item-p (name re-list &optional ignore-ext)
3755 ;; Return t if the buffer or file NAME should be ignored.
69beb26d
KS
3756 (or (member name ido-ignore-item-temp-list)
3757 (and
3758 ido-process-ignore-lists re-list
d6049c78
KS
3759 (save-match-data
3760 (let ((ext-list (and ignore-ext ido-ignore-extensions
789d1bf0 3761 completion-ignored-extensions))
d6049c78
KS
3762 (case-fold-search ido-case-fold)
3763 ignorep nextstr
3764 (flen (length name)) slen)
3765 (while ext-list
3766 (setq nextstr (car ext-list))
3767 (if (cond
3768 ((stringp nextstr)
3769 (and (>= flen (setq slen (length nextstr)))
3770 (string-equal (substring name (- flen slen)) nextstr)))
bf8b0f8b 3771 ((functionp nextstr) (funcall nextstr name))
d6049c78
KS
3772 (t nil))
3773 (setq ignorep t
3774 ext-list nil
3775 re-list nil)
3776 (setq ext-list (cdr ext-list))))
3777 (while re-list
3778 (setq nextstr (car re-list))
3779 (if (cond
3780 ((stringp nextstr) (string-match nextstr name))
bf8b0f8b 3781 ((functionp nextstr) (funcall nextstr name))
d6049c78
KS
3782 (t nil))
3783 (setq ignorep t
3784 re-list nil)
3785 (setq re-list (cdr re-list))))
3786 ;; return the result
3787 (if ignorep
3788 (setq ido-ignored-list (cons name ido-ignored-list)))
3789 ignorep)))))
789d1bf0
KS
3790
3791;; Private variable used by `ido-word-matching-substring'.
3792(defvar ido-change-word-sub)
3793
3794(defun ido-find-common-substring (items subs)
3795 ;; Return common string following SUBS in each element of ITEMS.
3796 (let (res
3797 alist
3798 ido-change-word-sub)
3799 (setq ido-change-word-sub
3800 (if ido-enable-regexp
3801 subs
3802 (regexp-quote subs)))
9066a4d0 3803 (setq res (mapcar #'ido-word-matching-substring items))
789d1bf0 3804 (setq res (delq nil res)) ;; remove any nil elements (shouldn't happen)
9066a4d0 3805 (setq alist (mapcar #'ido-makealist res)) ;; could use an OBARRAY
789d1bf0
KS
3806
3807 ;; try-completion returns t if there is an exact match.
9066a4d0
KS
3808 (let* ((completion-ignore-case ido-case-fold)
3809 (comp (try-completion subs alist)))
3810 (if (eq comp t)
3811 subs
3812 comp))))
789d1bf0
KS
3813
3814(defun ido-word-matching-substring (word)
3815 ;; Return part of WORD before 1st match to `ido-change-word-sub'.
3816 ;; If `ido-change-word-sub' cannot be found in WORD, return nil.
71296446 3817 (let ((case-fold-search ido-case-fold))
789d1bf0
KS
3818 (let ((m (string-match ido-change-word-sub (ido-name word))))
3819 (if m
3820 (substring (ido-name word) m)
3821 ;; else no match
3822 nil))))
3823
3824(defun ido-makealist (res)
3825 ;; Return dotted pair (RES . 1).
3826 (cons res 1))
3827
d5e63715 3828(defun ido-choose-completion-string (choice &rest ignored)
789d1bf0
KS
3829 (when (ido-active)
3830 ;; Insert the completion into the buffer where completion was requested.
3831 (if (get-buffer ido-completion-buffer)
3832 (kill-buffer ido-completion-buffer))
3833 (cond
3834 ((ido-active t) ;; ido-use-merged-list
3835 (setq ido-current-directory ""
3836 ido-text choice
3837 ido-exit 'done))
3838 ((not (ido-final-slash choice))
3839 (setq ido-text choice
3840 ido-exit 'done))
3841 (t
3842 (ido-set-current-directory ido-current-directory choice)
3843 (setq ido-exit 'refresh)))
3844 (exit-minibuffer)
3845 t))
3846
3847(defun ido-completion-help ()
3848 "Show possible completions in a *File Completions* buffer."
3849 (interactive)
3850 (setq ido-rescan nil)
3851 (let ((temp-buf (get-buffer ido-completion-buffer))
3852 display-it full-list)
3853 (if (and (eq last-command this-command) temp-buf)
3854 ;; scroll buffer
3855 (let (win (buf (current-buffer)))
3856 (display-buffer temp-buf nil nil)
3857 (set-buffer temp-buf)
3858 (setq win (get-buffer-window temp-buf))
3859 (if (pos-visible-in-window-p (point-max) win)
c05b0612
KS
3860 (if (or ido-completion-buffer-all-completions
3861 (boundp 'ido-completion-buffer-full))
789d1bf0 3862 (set-window-start win (point-min))
3729cc87
KS
3863 (with-no-warnings
3864 (set (make-local-variable 'ido-completion-buffer-full) t))
789d1bf0
KS
3865 (setq full-list t
3866 display-it t))
3867 (scroll-other-window))
3868 (set-buffer buf))
3869 (setq display-it t))
3870 (if display-it
3871 (with-output-to-temp-buffer ido-completion-buffer
1de0ae85 3872 (let ((completion-list (sort
789d1bf0 3873 (cond
c05b0612 3874 (ido-directory-too-big
1fd1a9f2 3875 (message "Reading directory...")
c05b0612
KS
3876 (setq ido-directory-too-big nil
3877 ido-ignored-list nil
3878 ido-cur-list (ido-all-completions)
3879 ido-rescan t)
3880 (ido-set-matches)
3881 (or ido-matches ido-cur-list))
789d1bf0
KS
3882 (ido-use-merged-list
3883 (ido-flatten-merged-list (or ido-matches ido-cur-list)))
3884 ((or full-list ido-completion-buffer-all-completions)
3885 (ido-all-completions))
3886 (t
1de0ae85
KS
3887 (copy-sequence (or ido-matches ido-cur-list))))
3888 #'ido-file-lessp)))
1518d6e3 3889 (if (featurep 'xemacs)
789d1bf0
KS
3890 ;; XEmacs extents are put on by default, doesn't seem to be
3891 ;; any way of switching them off.
0fe826e9 3892 ;; This obscure code avoids a byte compiler warning in Emacs.
6c1bc246
KS
3893 (let ((f 'display-completion-list))
3894 (funcall f completion-list
3895 :help-string "ido "
71296446 3896 :activate-callback
a09e21bf 3897 '(lambda (x y z) (message "Doesn't work yet, sorry!"))))
789d1bf0
KS
3898 ;; else running Emacs
3899 ;;(add-hook 'completion-setup-hook 'completion-setup-function)
3900 (display-completion-list completion-list)))))))
3901
2acfb954
ÓF
3902(defun ido-kill-buffer-internal (buf)
3903 "Kill buffer BUF and rebuild ido's buffer list if needed."
3904 (if (not (kill-buffer buf))
3905 ;; buffer couldn't be killed.
3906 (setq ido-rescan t)
3907 ;; else buffer was killed so remove name from list.
3908 (setq ido-cur-list (delq buf ido-cur-list))
3909 ;; Some packages, like uniquify.el, may rename buffers when one
3910 ;; is killed, so we need to test this condition to avoid using
3911 ;; an outdated list of buffer names. We don't want to always
3912 ;; rebuild the list of buffers, as this alters the previous
3913 ;; buffer order that the user was seeing on the prompt. However,
3914 ;; when we rebuild the list, we try to keep the previous second
3915 ;; buffer as the first one.
3916 (catch 'update
3917 (dolist (b ido-cur-list)
3918 (unless (get-buffer b)
3919 (setq ido-cur-list (ido-make-buffer-list (cadr ido-matches)))
3920 (setq ido-rescan t)
3921 (throw 'update nil))))))
3922
789d1bf0
KS
3923;;; KILL CURRENT BUFFER
3924(defun ido-kill-buffer-at-head ()
155943b9
KS
3925 "Kill the buffer at the head of `ido-matches'.
3926If cursor is not at the end of the user input, delete to end of input."
789d1bf0 3927 (interactive)
155943b9 3928 (if (not (eobp))
79ef5763 3929 (delete-region (point) (line-end-position))
155943b9
KS
3930 (let ((enable-recursive-minibuffers t)
3931 (buf (ido-name (car ido-matches))))
3932 (when buf
2acfb954 3933 (ido-kill-buffer-internal buf)
155943b9
KS
3934 ;; Check if buffer still exists.
3935 (if (get-buffer buf)
3936 ;; buffer couldn't be killed.
3937 (setq ido-rescan t)
3938 ;; else buffer was killed so remove name from list.
3939 (setq ido-cur-list (delq buf ido-cur-list)))))))
789d1bf0
KS
3940
3941;;; DELETE CURRENT FILE
3942(defun ido-delete-file-at-head ()
155943b9
KS
3943 "Delete the file at the head of `ido-matches'.
3944If cursor is not at the end of the user input, delete to end of input."
789d1bf0 3945 (interactive)
155943b9 3946 (if (not (eobp))
79ef5763 3947 (delete-region (point) (line-end-position))
155943b9
KS
3948 (let ((enable-recursive-minibuffers t)
3949 (file (ido-name (car ido-matches))))
3950 (if file
3951 (setq file (concat ido-current-directory file)))
3952 (when (and file
3953 (file-exists-p file)
3954 (not (file-directory-p file))
3955 (file-writable-p ido-current-directory)
3956 (yes-or-no-p (concat "Delete " file "? ")))
3957 (delete-file file)
3958 ;; Check if file still exists.
3959 (if (file-exists-p file)
3960 ;; file could not be deleted
3961 (setq ido-rescan t)
3962 ;; else file was killed so remove name from list.
3963 (setq ido-cur-list (delq (car ido-matches) ido-cur-list)))))))
789d1bf0
KS
3964
3965
3966;;; VISIT CHOSEN BUFFER
3967(defun ido-visit-buffer (buffer method &optional record)
a11ad595 3968 "Switch to BUFFER according to METHOD.
616e8e5f 3969Record command in `command-history' if optional RECORD is non-nil."
930f852e
KS
3970 (if (bufferp buffer)
3971 (setq buffer (buffer-name buffer)))
789d1bf0
KS
3972 (let (win newframe)
3973 (cond
3974 ((eq method 'kill)
3975 (if record
3976 (ido-record-command 'kill-buffer buffer))
2acfb954 3977 (ido-kill-buffer-internal buffer))
789d1bf0 3978
a11ad595 3979 ((eq method 'other-window)
789d1bf0
KS
3980 (if record
3981 (ido-record-command 'switch-to-buffer buffer))
3982 (switch-to-buffer-other-window buffer))
3983
3984 ((eq method 'display)
3985 (display-buffer buffer))
3986
a11ad595 3987 ((eq method 'other-frame)
1518d6e3 3988 (switch-to-buffer-other-frame buffer)
a11ad595
KS
3989 (select-frame-set-input-focus (selected-frame)))
3990
3991 ((and (memq method '(raise-frame maybe-frame))
3992 window-system
3993 (setq win (ido-buffer-window-other-frame buffer))
3994 (or (eq method 'raise-frame)
3995 (y-or-n-p "Jump to frame? ")))
3996 (setq newframe (window-frame win))
3997 (select-frame-set-input-focus newframe)
3998 (select-window win))
3999
4000 ;; (eq method 'selected-window)
4001 (t
4002 ;; No buffer in other frames...
4003 (if record
4004 (ido-record-command 'switch-to-buffer buffer))
4005 (switch-to-buffer buffer)
1518d6e3 4006 ))))
789d1bf0
KS
4007
4008
a11ad595 4009(defun ido-buffer-window-other-frame (buffer)
789d1bf0
KS
4010 ;; Return window pointer if BUFFER is visible in another frame.
4011 ;; If BUFFER is visible in the current frame, return nil.
4012 (let ((blist (ido-get-buffers-in-frames 'current)))
4013 ;;If the buffer is visible in current frame, return nil
69beb26d 4014 (if (member buffer blist)
789d1bf0
KS
4015 nil
4016 ;; maybe in other frame or icon
4017 (get-buffer-window buffer 0) ; better than 'visible
4018 )))
4019
4020
4021;;; ----------- IDONIZED FUNCTIONS ------------
4022
4023;;;###autoload
4024(defun ido-switch-buffer ()
4025 "Switch to another buffer.
4026The buffer is displayed according to `ido-default-buffer-method' -- the
4027default is to show it in the same window, unless it is already visible
4028in another frame.
4029
4030As you type in a string, all of the buffers matching the string are
3903655d 4031displayed if substring-matching is used \(default). Look at
616e8e5f
JB
4032`ido-enable-prefix' and `ido-toggle-prefix'. When you have found the
4033buffer you want, it can then be selected. As you type, most keys have
facf67fd 4034their normal keybindings, except for the following: \\<ido-buffer-completion-map>
789d1bf0
KS
4035
4036RET Select the buffer at the front of the list of matches. If the
4037list is empty, possibly prompt to create new buffer.
4038
4039\\[ido-select-text] Select the current prompt as the buffer.
4040If no buffer is found, prompt for a new one.
4041
4042\\[ido-next-match] Put the first element at the end of the list.
4043\\[ido-prev-match] Put the last element at the start of the list.
71296446 4044\\[ido-complete] Complete a common suffix to the current string that
789d1bf0
KS
4045matches all buffers. If there is only one match, select that buffer.
4046If there is no common suffix, show a list of all matching buffers
4047in a separate window.
4048\\[ido-edit-input] Edit input string.
4049\\[ido-fallback-command] Fallback to non-ido version of current command.
4050\\[ido-toggle-regexp] Toggle regexp searching.
4051\\[ido-toggle-prefix] Toggle between substring and prefix matching.
4052\\[ido-toggle-case] Toggle case-sensitive searching of buffer names.
4053\\[ido-completion-help] Show list of matching buffers in separate window.
a2cf0212 4054\\[ido-enter-find-file] Drop into `ido-find-file'.
789d1bf0
KS
4055\\[ido-kill-buffer-at-head] Kill buffer at head of buffer list.
4056\\[ido-toggle-ignore] Toggle ignoring buffers listed in `ido-ignore-buffers'."
4057 (interactive)
4058 (ido-buffer-internal ido-default-buffer-method))
4059
4060;;;###autoload
4061(defun ido-switch-buffer-other-window ()
4062 "Switch to another buffer and show it in another window.
4063The buffer name is selected interactively by typing a substring.
74a5d578 4064For details of keybindings, see `ido-switch-buffer'."
789d1bf0 4065 (interactive)
a11ad595 4066 (ido-buffer-internal 'other-window 'switch-to-buffer-other-window))
789d1bf0
KS
4067
4068;;;###autoload
4069(defun ido-display-buffer ()
4070 "Display a buffer in another window but don't select it.
4071The buffer name is selected interactively by typing a substring.
74a5d578 4072For details of keybindings, see `ido-switch-buffer'."
789d1bf0 4073 (interactive)
db9f395b 4074 (ido-buffer-internal 'display 'display-buffer nil nil nil 'ignore))
789d1bf0
KS
4075
4076;;;###autoload
4077(defun ido-kill-buffer ()
4078 "Kill a buffer.
4079The buffer name is selected interactively by typing a substring.
74a5d578 4080For details of keybindings, see `ido-switch-buffer'."
789d1bf0 4081 (interactive)
db9f395b 4082 (ido-buffer-internal 'kill 'kill-buffer "Kill buffer: " (buffer-name (current-buffer)) nil 'ignore))
789d1bf0
KS
4083
4084;;;###autoload
4085(defun ido-insert-buffer ()
4086 "Insert contents of a buffer in current buffer after point.
4087The buffer name is selected interactively by typing a substring.
74a5d578 4088For details of keybindings, see `ido-switch-buffer'."
789d1bf0 4089 (interactive)
db9f395b 4090 (ido-buffer-internal 'insert 'insert-buffer "Insert buffer: " nil nil 'ido-enter-insert-file))
789d1bf0
KS
4091
4092;;;###autoload
4093(defun ido-switch-buffer-other-frame ()
4094 "Switch to another buffer and show it in another frame.
4095The buffer name is selected interactively by typing a substring.
74a5d578 4096For details of keybindings, see `ido-switch-buffer'."
789d1bf0
KS
4097 (interactive)
4098 (if ido-mode
a11ad595 4099 (ido-buffer-internal 'other-frame)
789d1bf0
KS
4100 (call-interactively 'switch-to-buffer-other-frame)))
4101
4102;;;###autoload
4103(defun ido-find-file-in-dir (dir)
4104 "Switch to another file starting from DIR."
4105 (interactive "DDir: ")
72a75b41 4106 (setq dir (file-name-as-directory dir))
db9f395b 4107 (ido-file-internal ido-default-file-method nil dir nil nil nil 'ignore))
789d1bf0
KS
4108
4109;;;###autoload
4110(defun ido-find-file ()
4111 "Edit file with name obtained via minibuffer.
4112The file is displayed according to `ido-default-file-method' -- the
4113default is to show it in the same window, unless it is already
4114visible in another frame.
4115
616e8e5f
JB
4116The file name is selected interactively by typing a substring. As you
4117type in a string, all of the filenames matching the string are displayed
4118if substring-matching is used \(default). Look at `ido-enable-prefix' and
4119`ido-toggle-prefix'. When you have found the filename you want, it can
4120then be selected. As you type, most keys have their normal keybindings,
facf67fd 4121except for the following: \\<ido-file-completion-map>
789d1bf0
KS
4122
4123RET Select the file at the front of the list of matches. If the
4124list is empty, possibly prompt to create new file.
4125
4126\\[ido-select-text] Select the current prompt as the buffer or file.
4127If no buffer or file is found, prompt for a new one.
4128
4129\\[ido-next-match] Put the first element at the end of the list.
4130\\[ido-prev-match] Put the last element at the start of the list.
71296446 4131\\[ido-complete] Complete a common suffix to the current string that
789d1bf0
KS
4132matches all files. If there is only one match, select that file.
4133If there is no common suffix, show a list of all matching files
4134in a separate window.
362cdb61 4135\\[ido-edit-input] Edit input string (including directory).
789d1bf0
KS
4136\\[ido-prev-work-directory] or \\[ido-next-work-directory] go to previous/next directory in work directory history.
4137\\[ido-merge-work-directories] search for file in the work directory history.
4138\\[ido-forget-work-directory] removes current directory from the work directory history.
4139\\[ido-prev-work-file] or \\[ido-next-work-file] cycle through the work file history.
973495ca 4140\\[ido-wide-find-file-or-pop-dir] and \\[ido-wide-find-dir-or-delete-dir] prompts and uses find to locate files or directories.
789d1bf0
KS
4141\\[ido-make-directory] prompts for a directory to create in current directory.
4142\\[ido-fallback-command] Fallback to non-ido version of current command.
4143\\[ido-toggle-regexp] Toggle regexp searching.
4144\\[ido-toggle-prefix] Toggle between substring and prefix matching.
4145\\[ido-toggle-case] Toggle case-sensitive searching of file names.
4146\\[ido-toggle-vc] Toggle version control for this file.
4147\\[ido-toggle-literal] Toggle literal reading of this file.
4148\\[ido-completion-help] Show list of matching files in separate window.
4149\\[ido-toggle-ignore] Toggle ignoring files listed in `ido-ignore-files'."
4150
4151 (interactive)
4152 (ido-file-internal ido-default-file-method))
4153
4154;;;###autoload
4155(defun ido-find-file-other-window ()
4156 "Switch to another file and show it in another window.
4157The file name is selected interactively by typing a substring.
74a5d578 4158For details of keybindings, see `ido-find-file'."
789d1bf0 4159 (interactive)
a11ad595 4160 (ido-file-internal 'other-window 'find-file-other-window))
789d1bf0
KS
4161
4162;;;###autoload
4163(defun ido-find-alternate-file ()
4164 "Switch to another file and show it in another window.
4165The file name is selected interactively by typing a substring.
74a5d578 4166For details of keybindings, see `ido-find-file'."
789d1bf0
KS
4167 (interactive)
4168 (ido-file-internal 'alt-file 'find-alternate-file nil "Find alternate file: "))
4169
4170;;;###autoload
4171(defun ido-find-file-read-only ()
4172 "Edit file read-only with name obtained via minibuffer.
4173The file name is selected interactively by typing a substring.
74a5d578 4174For details of keybindings, see `ido-find-file'."
789d1bf0
KS
4175 (interactive)
4176 (ido-file-internal 'read-only 'find-file-read-only nil "Find file read-only: "))
4177
4178;;;###autoload
4179(defun ido-find-file-read-only-other-window ()
4180 "Edit file read-only in other window with name obtained via minibuffer.
4181The file name is selected interactively by typing a substring.
74a5d578 4182For details of keybindings, see `ido-find-file'."
789d1bf0
KS
4183 (interactive)
4184 (ido-file-internal 'read-only 'find-file-read-only-other-window nil "Find file read-only other window: "))
4185
4186;;;###autoload
4187(defun ido-find-file-read-only-other-frame ()
4188 "Edit file read-only in other frame with name obtained via minibuffer.
4189The file name is selected interactively by typing a substring.
74a5d578 4190For details of keybindings, see `ido-find-file'."
789d1bf0
KS
4191 (interactive)
4192 (ido-file-internal 'read-only 'find-file-read-only-other-frame nil "Find file read-only other frame: "))
4193
4194;;;###autoload
4195(defun ido-display-file ()
4196 "Display a file in another window but don't select it.
4197The file name is selected interactively by typing a substring.
74a5d578 4198For details of keybindings, see `ido-find-file'."
789d1bf0 4199 (interactive)
db9f395b 4200 (ido-file-internal 'display nil nil nil nil nil 'ignore))
789d1bf0
KS
4201
4202;;;###autoload
4203(defun ido-find-file-other-frame ()
4204 "Switch to another file and show it in another frame.
4205The file name is selected interactively by typing a substring.
74a5d578 4206For details of keybindings, see `ido-find-file'."
789d1bf0 4207 (interactive)
a11ad595 4208 (ido-file-internal 'other-frame 'find-file-other-frame))
789d1bf0
KS
4209
4210;;;###autoload
4211(defun ido-write-file ()
4212 "Write current buffer to a file.
4213The file name is selected interactively by typing a substring.
74a5d578 4214For details of keybindings, see `ido-find-file'."
789d1bf0
KS
4215 (interactive)
4216 (let ((ido-process-ignore-lists t)
4217 (ido-work-directory-match-only nil)
4218 (ido-ignore-files (cons "[^/]\\'" ido-ignore-files))
4219 (ido-report-no-match nil)
d81aa76a 4220 (ido-confirm-unique-completion t)
789d1bf0 4221 (ido-auto-merge-work-directories-length -1))
db9f395b 4222 (ido-file-internal 'write 'write-file nil "Write file: " nil nil 'ignore)))
789d1bf0
KS
4223
4224;;;###autoload
4225(defun ido-insert-file ()
4226 "Insert contents of file in current buffer.
4227The file name is selected interactively by typing a substring.
74a5d578 4228For details of keybindings, see `ido-find-file'."
789d1bf0 4229 (interactive)
db9f395b 4230 (ido-file-internal 'insert 'insert-file nil "Insert file: " nil nil 'ido-enter-insert-buffer))
789d1bf0
KS
4231
4232;;;###autoload
4233(defun ido-dired ()
a09e21bf 4234 "Call `dired' the ido way.
789d1bf0 4235The directory is selected interactively by typing a substring.
74a5d578 4236For details of keybindings, see `ido-find-file'."
789d1bf0
KS
4237 (interactive)
4238 (let ((ido-report-no-match nil)
4239 (ido-auto-merge-work-directories-length -1))
4240 (ido-file-internal 'dired 'dired nil "Dired: " 'dir)))
4241
4242(defun ido-list-directory ()
a09e21bf 4243 "Call `list-directory' the ido way.
789d1bf0 4244The directory is selected interactively by typing a substring.
74a5d578 4245For details of keybindings, see `ido-find-file'."
789d1bf0
KS
4246 (interactive)
4247 (let ((ido-report-no-match nil)
4248 (ido-auto-merge-work-directories-length -1))
4249 (ido-file-internal 'list-directory 'list-directory nil "List directory: " 'dir)))
4250
4251;;; XEmacs hack for showing default buffer
4252
4253;; The first time we enter the minibuffer, Emacs puts up the default
4254;; buffer to switch to, but XEmacs doesn't -- presumably there is a
4255;; subtle difference in the two versions of post-command-hook. The
4256;; default is shown for both whenever we delete all of our text
4257;; though, indicating its just a problem the first time we enter the
4258;; function. To solve this, we use another entry hook for emacs to
4259;; show the default the first time we enter the minibuffer.
4260
4261
4262;;; ICOMPLETE TYPE CODE
4263
4264(defun ido-initiate-auto-merge (buffer)
4265 (ido-trace "\n*merge timeout*" buffer)
4266 (setq ido-auto-merge-timer nil)
4267 (when (and (buffer-live-p buffer)
cba9a3a5 4268 (ido-active)
789d1bf0
KS
4269 (boundp 'ido-eoinput) ido-eoinput)
4270 (let ((contents (buffer-substring-no-properties (minibuffer-prompt-end) ido-eoinput)))
4271 (ido-trace "request merge")
4272 (setq ido-use-merged-list 'auto
4273 ido-text-init contents
4274 ido-rotate-temp t
4275 ido-exit 'refresh)
7fdbcd83 4276 (with-current-buffer buffer
789d1bf0
KS
4277 (ido-tidy))
4278 (throw 'ido contents))))
4279
4280(defun ido-exhibit ()
4281 "Post command hook for `ido'."
4282 ;; Find matching files and display a list in the minibuffer.
4283 ;; Copied from `icomplete-exhibit' with two changes:
4284 ;; 1. It prints a default file name when there is no text yet entered.
4285 ;; 2. It calls my completion routine rather than the standard completion.
4286
cba9a3a5 4287 (when (ido-active)
bad111c2
KS
4288 (let ((contents (buffer-substring-no-properties (minibuffer-prompt-end) (point-max)))
4289 (buffer-undo-list t)
4290 try-single-dir-match
4291 refresh)
789d1bf0 4292
5444f278
KS
4293 (when ido-trace-enable
4294 (ido-trace "\nexhibit" this-command)
4295 (ido-trace "dir" ido-current-directory)
4296 (ido-trace "contents" contents)
4297 (ido-trace "list" ido-cur-list)
4298 (ido-trace "matches" ido-matches)
4299 (ido-trace "rescan" ido-rescan))
789d1bf0 4300
bad111c2
KS
4301 (save-excursion
4302 (goto-char (point-max))
4303 ;; Register the end of input, so we know where the extra stuff (match-status info) begins:
4304 (unless (boundp 'ido-eoinput)
4305 ;; In case it got wiped out by major mode business:
4306 (make-local-variable 'ido-eoinput))
4307 (setq ido-eoinput (point))
4308
4309 ;; Handle explicit directory changes
4310 (cond
db9f395b 4311 ((memq ido-cur-item '(buffer list))
bad111c2
KS
4312 )
4313
4314 ((= (length contents) 0)
4315 )
4316
4317 ((= (length contents) 1)
dfebc0ae
KS
4318 (cond
4319 ((and (ido-is-tramp-root) (string-equal contents "/"))
bad111c2
KS
4320 (ido-set-current-directory ido-current-directory contents)
4321 (setq refresh t))
4c2ee078 4322 ((and (ido-unc-hosts) (string-equal contents "/")
dfebc0ae
KS
4323 (let ((ido-enable-tramp-completion nil))
4324 (ido-is-root-directory)))
4325 (ido-set-current-directory "//")
4326 (setq refresh t))
4327 ))
bad111c2 4328
10b19e88
KS
4329 ((and (string-match (if ido-enable-tramp-completion ".[:@]\\'" ".:\\'") contents)
4330 (ido-is-root-directory) ;; Ange-ftp or tramp
4331 (not (ido-local-file-exists-p contents)))
bad111c2
KS
4332 (ido-set-current-directory ido-current-directory contents)
4333 (when (ido-is-slow-ftp-host)
4334 (setq ido-exit 'fallback)
4335 (exit-minibuffer))
4336 (setq refresh t))
4337
4338 ((ido-final-slash contents) ;; xxx/
4339 (ido-trace "final slash" contents)
71296446 4340 (cond
bad111c2
KS
4341 ((string-equal contents "~/")
4342 (ido-set-current-home)
4343 (setq refresh t))
4344 ((string-equal contents "../")
4345 (ido-up-directory t)
4346 (setq refresh t))
4347 ((string-equal contents "./")
4348 (setq refresh t))
1c36d72a 4349 ((string-match "\\`~[-_a-zA-Z0-9]+[$]?/\\'" contents)
bad111c2
KS
4350 (ido-trace "new home" contents)
4351 (ido-set-current-home contents)
4352 (setq refresh t))
4353 ((string-match "[$][A-Za-z0-9_]+/\\'" contents)
4354 (let ((exp (condition-case ()
4355 (expand-file-name
4356 (substitute-in-file-name (substring contents 0 -1))
4357 ido-current-directory)
4358 (error nil))))
4359 (ido-trace contents exp)
4360 (when (and exp (file-directory-p exp))
4361 (ido-set-current-directory (file-name-directory exp))
4362 (setq ido-text-init (file-name-nondirectory exp))
4363 (setq refresh t))))
4364 ((and (memq system-type '(windows-nt ms-dos))
4365 (string-equal (substring contents 1) ":/"))
4366 (ido-set-current-directory (file-name-directory contents))
4367 (setq refresh t))
4368 ((string-equal (substring contents -2 -1) "/")
71296446 4369 (ido-set-current-directory
bad111c2
KS
4370 (if (memq system-type '(windows-nt ms-dos))
4371 (expand-file-name "/" ido-current-directory)
4372 "/"))
4373 (setq refresh t))
cb65c373 4374 ((and (or ido-directory-nonreadable ido-directory-too-big)
a70343bd 4375 (file-directory-p (concat ido-current-directory (file-name-directory contents))))
d81aa76a 4376 (ido-set-current-directory
a70343bd
KS
4377 (concat ido-current-directory (file-name-directory contents)))
4378 (setq refresh t))
bad111c2
KS
4379 (t
4380 (ido-trace "try single dir")
4381 (setq try-single-dir-match t))))
4382
4383 ((and (string-equal (substring contents -2 -1) "/")
4384 (not (string-match "[$]" contents)))
4385 (ido-set-current-directory
4386 (cond
4387 ((= (length contents) 2)
4388 "/")
4389 (ido-matches
5a1b28a4 4390 (concat ido-current-directory (ido-name (car ido-matches))))
bad111c2
KS
4391 (t
4392 (concat ido-current-directory (substring contents 0 -1)))))
4393 (setq ido-text-init (substring contents -1))
4394 (setq refresh t))
4395
4396 ((and (not ido-use-merged-list)
4397 (not (ido-final-slash contents))
4398 (eq ido-try-merged-list t)
4399 (numberp ido-auto-merge-work-directories-length)
4400 (> ido-auto-merge-work-directories-length 0)
4401 (= (length contents) ido-auto-merge-work-directories-length)
4402 (not (and ido-auto-merge-inhibit-characters-regexp
4403 (string-match ido-auto-merge-inhibit-characters-regexp contents)))
4404 (not (input-pending-p)))
4405 (setq ido-use-merged-list 'auto
4406 ido-text-init contents
4407 ido-rotate-temp t)
4408 (setq refresh t))
4409
4410 (t nil))
4411
4412 (when refresh
4413 (ido-trace "refresh on /" ido-text-init)
4414 (setq ido-exit 'refresh)
4415 (exit-minibuffer))
789d1bf0 4416
bad111c2
KS
4417 ;; Update the list of matches
4418 (setq ido-text contents)
4419 (ido-set-matches)
4420 (ido-trace "new " ido-matches)
4421
5702da69 4422 (when (and ido-enter-matching-directory
bad111c2 4423 ido-matches
5702da69
KS
4424 (or (eq ido-enter-matching-directory 'first)
4425 (null (cdr ido-matches)))
5a1b28a4 4426 (ido-final-slash (ido-name (car ido-matches)))
bad111c2 4427 (or try-single-dir-match
5702da69 4428 (eq ido-enter-matching-directory t)))
bad111c2 4429 (ido-trace "single match" (car ido-matches))
71296446 4430 (ido-set-current-directory
5a1b28a4 4431 (concat ido-current-directory (ido-name (car ido-matches))))
bad111c2
KS
4432 (setq ido-exit 'refresh)
4433 (exit-minibuffer))
4434
4435 (when (and (not ido-matches)
a70343bd 4436 (not ido-directory-nonreadable)
cb65c373 4437 (not ido-directory-too-big)
bad111c2 4438 ;; ido-rescan ?
789d1bf0
KS
4439 ido-process-ignore-lists
4440 ido-ignored-list)
bad111c2
KS
4441 (let ((ido-process-ignore-lists nil)
4442 (ido-rotate ido-rotate)
4443 (ido-cur-list ido-ignored-list))
4444 (ido-trace "try all" ido-ignored-list)
4445 (ido-set-matches))
4446 (when ido-matches
4447 (ido-trace "found " ido-matches)
4448 (setq ido-rescan t)
4449 (setq ido-process-ignore-lists-inhibit t)
4450 (setq ido-text-init ido-text)
4451 (setq ido-exit 'refresh)
4452 (exit-minibuffer)))
4453
4454 (when (and
4455 ido-rescan
4456 (not ido-matches)
4457 (memq ido-cur-item '(file dir))
4458 (not (ido-is-root-directory))
4459 (> (length contents) 1)
a70343bd 4460 (not (string-match "[$]" contents))
cb65c373
KS
4461 (not ido-directory-nonreadable)
4462 (not ido-directory-too-big))
bad111c2
KS
4463 (ido-trace "merge?")
4464 (if ido-use-merged-list
4465 (ido-undo-merge-work-directory contents nil)
4466 (when (and (eq ido-try-merged-list t)
4467 (numberp ido-auto-merge-work-directories-length)
4468 (= ido-auto-merge-work-directories-length 0)
4469 (not (and ido-auto-merge-inhibit-characters-regexp
4470 (string-match ido-auto-merge-inhibit-characters-regexp contents)))
4471 (not (input-pending-p)))
4472 (ido-trace "\n*start timer*")
4473 (setq ido-auto-merge-timer
4474 (run-with-timer ido-auto-merge-delay-time nil 'ido-initiate-auto-merge (current-buffer))))))
71296446 4475
bad111c2 4476 (setq ido-rescan t)
789d1bf0 4477
71296446 4478 (if (and ido-use-merged-list
bad111c2
KS
4479 ido-matches
4480 (not (string-equal (car (cdr (car ido-matches))) ido-current-directory)))
4481 (progn
4482 (ido-set-current-directory (car (cdr (car ido-matches))))
4483 (setq ido-use-merged-list t
4484 ido-exit 'keep
4485 ido-text-init ido-text)
4486 (exit-minibuffer)))
4487
4488 ;; Insert the match-status information:
4489 (ido-set-common-completion)
71296446 4490 (let ((inf (ido-completions
bad111c2
KS
4491 contents
4492 minibuffer-completion-table
4493 minibuffer-completion-predicate
4494 (not minibuffer-completion-confirm))))
11c238b3 4495 (setq ido-show-confirm-message nil)
bad111c2
KS
4496 (ido-trace "inf" inf)
4497 (insert inf))
4498 ))))
789d1bf0
KS
4499
4500(defun ido-completions (name candidates predicate require-match)
4501 ;; Return the string that is displayed after the user's text.
4502 ;; Modified from `icomplete-completions'.
71296446 4503
789d1bf0
KS
4504 (let* ((comps ido-matches)
4505 (ind (and (consp (car comps)) (> (length (cdr (car comps))) 1)
4506 ido-merged-indicator))
4507 first)
4508
4509 (if (and ind ido-use-faces)
ccba8bb6 4510 (put-text-property 0 1 'face 'ido-indicator ind))
71296446 4511
789d1bf0
KS
4512 (if (and ido-use-faces comps)
4513 (let* ((fn (ido-name (car comps)))
4514 (ln (length fn)))
4515 (setq first (format "%s" fn))
4516 (put-text-property 0 ln 'face
4517 (if (= (length comps) 1)
665ed61a
KS
4518 (if ido-incomplete-regexp
4519 'ido-incomplete-regexp
4520 'ido-only-match)
ccba8bb6 4521 'ido-first-match)
789d1bf0
KS
4522 first)
4523 (if ind (setq first (concat first ind)))
4524 (setq comps (cons first (cdr comps)))))
4525
4526 (cond ((null comps)
a70343bd 4527 (cond
11c238b3 4528 (ido-show-confirm-message
5b54c385 4529 (or (nth 10 ido-decorations) " [Confirm]"))
a70343bd
KS
4530 (ido-directory-nonreadable
4531 (or (nth 8 ido-decorations) " [Not readable]"))
cb65c373
KS
4532 (ido-directory-too-big
4533 (or (nth 9 ido-decorations) " [Too big]"))
a70343bd
KS
4534 (ido-report-no-match
4535 (nth 6 ido-decorations)) ;; [No match]
4536 (t "")))
665ed61a
KS
4537 (ido-incomplete-regexp
4538 (concat " " (car comps)))
789d1bf0 4539 ((null (cdr comps)) ;one match
665ed61a
KS
4540 (concat (if (if (not ido-enable-regexp)
4541 (= (length (ido-name (car comps))) (length name))
4542 ;; We can't rely on the length of the input
4543 ;; for regexps, so explicitly check for a
4544 ;; complete match
4545 (string-match name (ido-name (car comps)))
4546 (string-equal (match-string 0 (ido-name (car comps)))
4547 (ido-name (car comps))))
4548 ""
4549 ;; when there is one match, show the matching file name in full
4550 (concat (nth 4 ido-decorations) ;; [ ... ]
4551 (ido-name (car comps))
4552 (nth 5 ido-decorations)))
789d1bf0
KS
4553 (if (not ido-use-faces) (nth 7 ido-decorations)))) ;; [Matched]
4554 (t ;multiple matches
4555 (let* ((items (if (> ido-max-prospects 0) (1+ ido-max-prospects) 999))
4556 (alternatives
4557 (apply
71296446 4558 #'concat
789d1bf0 4559 (cdr (apply
9066a4d0
KS
4560 #'nconc
4561 (mapcar
4562 (lambda (com)
4563 (setq com (ido-name com))
4564 (setq items (1- items))
4565 (cond
4566 ((< items 0) ())
4567 ((= items 0) (list (nth 3 ido-decorations))) ; " | ..."
4568 (t
4569 (list (or ido-separator (nth 2 ido-decorations)) ; " | "
4570 (let ((str (substring com 0)))
4571 (if (and ido-use-faces
4572 (not (string= str first))
4573 (ido-final-slash str))
ccba8bb6 4574 (put-text-property 0 (length str) 'face 'ido-subdir str))
9066a4d0
KS
4575 str)))))
4576 comps))))))
789d1bf0
KS
4577
4578 (concat
4579 ;; put in common completion item -- what you get by pressing tab
9066a4d0
KS
4580 (if (and (stringp ido-common-match-string)
4581 (> (length ido-common-match-string) (length name)))
789d1bf0
KS
4582 (concat (nth 4 ido-decorations) ;; [ ... ]
4583 (substring ido-common-match-string (length name))
4584 (nth 5 ido-decorations)))
4585 ;; list all alternatives
4586 (nth 0 ido-decorations) ;; { ... }
4587 alternatives
4588 (nth 1 ido-decorations)))))))
4589
4590(defun ido-minibuffer-setup ()
4591 "Minibuffer setup hook for `ido'."
4592 ;; Copied from `icomplete-minibuffer-setup-hook'.
cba9a3a5 4593 (when (ido-active)
789d1bf0
KS
4594 (add-hook 'pre-command-hook 'ido-tidy nil t)
4595 (add-hook 'post-command-hook 'ido-exhibit nil t)
4596 (setq cua-inhibit-cua-keys t)
1518d6e3 4597 (when (featurep 'xemacs)
789d1bf0
KS
4598 (ido-exhibit)
4599 (goto-char (point-min)))
155943b9
KS
4600 (run-hooks 'ido-minibuffer-setup-hook)
4601 (when ido-initial-position
4602 (goto-char (+ (minibuffer-prompt-end) ido-initial-position))
4603 (setq ido-initial-position nil))))
789d1bf0
KS
4604
4605(defun ido-tidy ()
4606 "Pre command hook for `ido'."
4607 ;; Remove completions display, if any, prior to new user input.
4608 ;; Copied from `icomplete-tidy'."
4609
4610 (when ido-auto-merge-timer
4611 (ido-trace "\n*cancel timer*" this-command)
4612 (cancel-timer ido-auto-merge-timer)
4613 (setq ido-auto-merge-timer nil))
4614
cba9a3a5 4615 (if (ido-active)
789d1bf0
KS
4616 (if (and (boundp 'ido-eoinput)
4617 ido-eoinput)
71296446 4618
789d1bf0
KS
4619 (if (> ido-eoinput (point-max))
4620 ;; Oops, got rug pulled out from under us - reinit:
4621 (setq ido-eoinput (point-max))
4622 (let ((buffer-undo-list t))
4623 (delete-region ido-eoinput (point-max))))
71296446 4624
789d1bf0
KS
4625 ;; Reestablish the local variable 'cause minibuffer-setup is weird:
4626 (make-local-variable 'ido-eoinput)
4627 (setq ido-eoinput 1))))
4628
4629(defun ido-summary-buffers-to-end ()
4630 ;; Move the summaries to the end of the buffer list.
4631 ;; This is an example function which can be hooked on to
4632 ;; `ido-make-buffer-list-hook'. Any buffer matching the regexps
4633 ;; `Summary' or `output\*$'are put to the end of the list.
71296446
JB
4634 (let ((summaries (delq nil (mapcar
4635 (lambda (x)
4636 (if (or
789d1bf0
KS
4637 (string-match "Summary" x)
4638 (string-match "output\\*\\'" x))
4639 x))
4640 ido-temp-list))))
4641 (ido-to-end summaries)))
4642
4643;;; Helper functions for other programs
4644
84263efb 4645(put 'dired-do-rename 'ido 'ignore)
ae9d279d 4646(put 'ibuffer-find-file 'ido 'find-file)
76ce3ae6 4647(put 'dired-other-window 'ido 'dir)
84263efb 4648
cb65c373
KS
4649;;;###autoload
4650(defun ido-read-buffer (prompt &optional default require-match)
4651 "Ido replacement for the built-in `read-buffer'.
4652Return the name of a buffer selected.
4653PROMPT is the prompt to give to the user. DEFAULT if given is the default
4654buffer to be selected, which will go to the front of the list.
616e8e5f 4655If REQUIRE-MATCH is non-nil, an existing buffer must be selected."
cb65c373
KS
4656 (let* ((ido-current-directory nil)
4657 (ido-directory-nonreadable nil)
4658 (ido-directory-too-big nil)
4659 (ido-context-switch-command 'ignore)
4660 (buf (ido-read-internal 'buffer prompt 'ido-buffer-history default require-match)))
4661 (if (eq ido-exit 'fallback)
4662 (let ((read-buffer-function nil))
b2d4c118 4663 (run-hook-with-args 'ido-before-fallback-functions 'read-buffer)
cb65c373
KS
4664 (read-buffer prompt default require-match))
4665 buf)))
4666
789d1bf0
KS
4667;;;###autoload
4668(defun ido-read-file-name (prompt &optional dir default-filename mustmatch initial predicate)
cb65c373
KS
4669 "Ido replacement for the built-in `read-file-name'.
4670Read file name, prompting with PROMPT and completing in directory DIR.
789d1bf0 4671See `read-file-name' for additional parameters."
db9f395b
KS
4672 (let (filename)
4673 (cond
4674 ((or (eq predicate 'file-directory-p)
4675 (eq (get this-command 'ido) 'dir)
4676 (memq this-command ido-read-file-name-as-directory-commands))
4677 (setq filename
89a28f0b
KS
4678 (ido-read-directory-name prompt dir default-filename mustmatch initial))
4679 (if (eq ido-exit 'fallback)
4680 (setq filename 'fallback)))
db9f395b
KS
4681 ((and (not (eq (get this-command 'ido) 'ignore))
4682 (not (memq this-command ido-read-file-name-non-ido))
4683 (or (null predicate) (eq predicate 'file-exists-p)))
4684 (let* (ido-saved-vc-hb
ae9d279d
KS
4685 (ido-context-switch-command
4686 (if (eq (get this-command 'ido) 'find-file) nil 'ignore))
db9f395b 4687 (vc-handled-backends (and (boundp 'vc-handled-backends) vc-handled-backends))
83a12f3a 4688 (minibuffer-completing-file-name t)
db9f395b
KS
4689 (ido-current-directory (ido-expand-directory dir))
4690 (ido-directory-nonreadable (not (file-readable-p ido-current-directory)))
cb65c373
KS
4691 (ido-directory-too-big (and (not ido-directory-nonreadable)
4692 (ido-directory-too-big-p ido-current-directory)))
db9f395b 4693 (ido-work-directory-index -1)
fcbc95a9
KS
4694 (ido-show-dot-for-dired (and ido-show-dot-for-dired
4695 (not default-filename)))
db9f395b
KS
4696 (ido-work-file-index -1)
4697 (ido-find-literal nil))
4698 (setq ido-exit nil)
4699 (setq filename
4700 (ido-read-internal 'file prompt 'ido-file-history default-filename mustmatch initial))
4701 (cond
4702 ((eq ido-exit 'fallback)
4703 (setq filename 'fallback))
ae9d279d
KS
4704 ((eq ido-exit 'dired)
4705 (setq filename ido-current-directory))
db9f395b
KS
4706 (filename
4707 (setq filename
4708 (concat ido-current-directory filename))))))
4709 (t
4710 (setq filename 'fallback)))
4711 (if (eq filename 'fallback)
4712 (let ((read-file-name-function nil))
b2d4c118 4713 (run-hook-with-args 'ido-before-fallback-functions 'read-file-name)
db9f395b
KS
4714 (read-file-name prompt dir default-filename mustmatch initial predicate))
4715 filename)))
789d1bf0
KS
4716
4717;;;###autoload
4718(defun ido-read-directory-name (prompt &optional dir default-dirname mustmatch initial)
cb65c373
KS
4719 "Ido replacement for the built-in `read-directory-name'.
4720Read directory name, prompting with PROMPT and completing in directory DIR.
4721See `read-directory-name' for additional parameters."
a70343bd 4722 (let* (filename
83a12f3a 4723 (minibuffer-completing-file-name t)
db9f395b 4724 (ido-context-switch-command 'ignore)
a70343bd
KS
4725 ido-saved-vc-hb
4726 (ido-current-directory (ido-expand-directory dir))
4727 (ido-directory-nonreadable (not (file-readable-p ido-current-directory)))
cb65c373
KS
4728 (ido-directory-too-big (and (not ido-directory-nonreadable)
4729 (ido-directory-too-big-p ido-current-directory)))
a70343bd
KS
4730 (ido-work-directory-index -1)
4731 (ido-work-file-index -1))
789d1bf0
KS
4732 (setq filename
4733 (ido-read-internal 'dir prompt 'ido-file-history default-dirname mustmatch initial))
4734 (if filename
4735 (if (and (stringp filename) (string-equal filename "."))
4736 ido-current-directory
4737 (concat ido-current-directory filename)))))
4738
db9f395b
KS
4739;;;###autoload
4740(defun ido-completing-read (prompt choices &optional predicate require-match initial-input hist def)
cb65c373
KS
4741 "Ido replacement for the built-in `completing-read'.
4742Read a string in the minibuffer with ido-style completion.
db9f395b
KS
4743PROMPT is a string to prompt with; normally it ends in a colon and a space.
4744CHOICES is a list of strings which are the possible completions.
4745PREDICATE is currently ignored; it is included to be compatible
4746 with `completing-read'.
4747If REQUIRE-MATCH is non-nil, the user is not allowed to exit unless
4748 the input is (or completes to) an element of CHOICES or is null.
4749 If the input is null, `ido-completing-read' returns DEF, or an empty
4750 string if DEF is nil, regardless of the value of REQUIRE-MATCH.
4751If INITIAL-INPUT is non-nil, insert it in the minibuffer initially,
4752 with point positioned at the end.
4753HIST, if non-nil, specifies a history list.
4754DEF, if non-nil, is the default value."
4755 (let ((ido-current-directory nil)
4756 (ido-directory-nonreadable nil)
cb65c373 4757 (ido-directory-too-big nil)
db9f395b
KS
4758 (ido-context-switch-command 'ignore)
4759 (ido-choice-list choices))
4760 (ido-read-internal 'list prompt hist def require-match initial-input)))
4761
4e3e159b
JB
4762(defun ido-unload-function ()
4763 "Unload the Ido library."
4764 (ido-mode -1)
4765 (setq minor-mode-map-alist (assq-delete-all 'ido-mode minor-mode-map-alist))
4766 ;; continue standard unloading
4767 nil)
4768
403dae9d 4769(provide 'ido)
db9f395b 4770
3da360a7 4771;; arch-tag: b63a3500-1735-41bd-8a01-05373f0864da
789d1bf0 4772;;; ido.el ends here