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