]> code.delx.au - gnu-emacs/blobdiff - lisp/ido.el
(redraw-calendar): Preserve point. Reported by Matt Hodges
[gnu-emacs] / lisp / ido.el
index ae376741f1bae3b2755bdf6dcf48b51af7da5b7e..86a88d0d491d3b73524f8e4a50e7f042ea1ce9ad 100644 (file)
   "Switch between files using substrings."
   :group 'extensions
   :group 'convenience
+  :version "22.1"
   :link '(emacs-commentary-link :tag "Commentary" "ido.el")
   :link '(emacs-library-link :tag "Lisp File" "ido.el"))
 
@@ -359,7 +360,6 @@ use either \\[customize] or the function `ido-mode'."
   :require 'ido
   :link '(emacs-commentary-link "ido.el")
   :set-after '(ido-save-directory-list-file)
-  :version "21.4"
   :type '(choice (const :tag "Turn on only buffer" buffer)
                  (const :tag "Turn on only file" file)
                  (const :tag "Turn on both buffer and file" both)
@@ -410,6 +410,15 @@ This allows the current directory to be opened immediate with `dired'."
   :type 'boolean
   :group 'ido)
 
+(defcustom ido-file-extensions-order nil
+  "*List of file extensions specifying preferred order of file selections.
+Each element is either a string with `.' as the first char, an empty
+string matching files without extension, or t which is the default order
+of for files with an unlisted file extension."
+  :type '(repeat (choice string
+                        (const :tag "Default order" t)))
+  :group 'ido)
+
 (defcustom ido-ignore-directories
   '("\\`CVS/" "\\`\\.\\./" "\\`\\./")
   "*List of regexps or functions matching sub-directory names to ignore."
@@ -482,14 +491,20 @@ Value can be toggled within `ido' using `ido-toggle-regexp'."
   :group 'ido)
 
 (defcustom ido-enable-prefix nil
-  "*Nil means that `ido' will match if the inserted text is an
-arbitrary substring (default). If non-nil `ido' will only match if the inserted
-text is a prefix \(this behavior is like the standard unix- or
-emacs-completion works).
+  "*Non-nil means only match if the entered text is a prefix of file name.
+This behavior is like the standard emacs-completion.
+Nil means to match if the entered text is an arbitrary substring.
 Value can be toggled within `ido' using `ido-toggle-prefix'."
   :type 'boolean
   :group 'ido)
 
+(defcustom ido-enable-dot-prefix nil
+  "*Non-nil means to match leading dot as prefix.
+I.e. hidden files and buffers will match only if you type a dot
+as first char even if `ido-enable-prefix' is nil."
+  :type 'boolean
+  :group 'ido)
+
 (defcustom ido-confirm-unique-completion nil
   "*Non-nil means that even a unique completion must be confirmed.
 This means that \\[ido-complete] must always be followed by \\[ido-exit-minibuffer]
@@ -660,6 +675,14 @@ See also `ido-dir-file-cache' and `ido-save-directory-list-file'."
   :type 'integer
   :group 'ido)
 
+(defcustom ido-max-directory-size 30000
+  "*Maximum size (in bytes) for directories to use ido completion.
+If you enter a directory with a size larger than this size, ido will
+not provide the normal completion.  To show the completions, use C-a."
+  :type '(choice (const :tag "No limit" nil)
+                (integer :tag "Size in bytes" 30000))
+  :group 'ido)
+
 (defcustom ido-rotate-file-list-default nil
   "*Non-nil means that `ido' will always rotate file list to get default in front."
   :type 'boolean
@@ -693,9 +716,9 @@ Obsolete.  Set 3rd element of `ido-decorations' instead."
   :type '(choice string (const nil))
   :group 'ido)
 
-(defcustom ido-decorations '( "{" "}" " | " " | ..." "[" "]" " [No match]" " [Matched]" " [Not readable]")
+(defcustom ido-decorations '( "{" "}" " | " " | ..." "[" "]" " [No match]" " [Matched]" " [Not readable]" " [Too big]")
   "*List of strings used by ido to display the alternatives in the minibuffer.
-There are 9 elements in this list:
+There are 10 elements in this list:
 1st and 2nd elements are used as brackets around the prospect list,
 3rd element is the separator between prospects (ignored if ido-separator is set),
 4th element is the string inserted at the end of a truncated list of prospects,
@@ -703,7 +726,8 @@ There are 9 elements in this list:
 can be completed using TAB,
 7th element is the string displayed when there are a no matches, and
 8th element is displayed if there is a single match (and faces are not used).
-9th element is displayed when the current directory is non-readable."
+9th element is displayed when the current directory is non-readable.
+10th element is displayed when directory exceeds `ido-max-directory-size'."
   :type '(repeat string)
   :group 'ido)
 
@@ -927,7 +951,7 @@ it doesn't interfere with other minibuffer usage.")
 ;;; Variables with dynamic bindings.
 ;;; Declared here to keep the byte compiler quiet.
 
-;; Stores the current ido item type ('file, 'dir or 'buffer).
+;; Stores the current ido item type ('file, 'dir, 'buffer, or 'list).
 (defvar ido-cur-item)
 
 ;; Stores the current list of items that will be searched through.
@@ -936,6 +960,9 @@ it doesn't interfere with other minibuffer usage.")
 ;; at the end of the list.  Created by `ido-make-item-list'.
 (defvar ido-cur-list)
 
+;; Stores the choice list for ido-completing-read
+(defvar ido-choice-list)
+
 ;; Stores the list of items which are ignored when building
 ;; `ido-cur-list'.  It is in no specific order.
 (defvar ido-ignored-list)
@@ -943,6 +970,9 @@ it doesn't interfere with other minibuffer usage.")
 ;; Remember if current directory is non-readable (so we cannot do completion).
 (defvar ido-directory-nonreadable)
 
+;; Remember if current directory is 'huge' (so we don't want to do completion).
+(defvar ido-directory-too-big)
+
 ;; Keep current item list if non-nil.
 (defvar ido-keep-item-list)
 
@@ -986,6 +1016,8 @@ it doesn't interfere with other minibuffer usage.")
 ;; Stores temporary state of literal find file.
 (defvar ido-find-literal)
 
+;; Set to 'ignore to inhibit switching between find-file/switch-buffer.
+(defvar ido-context-switch-command)
 
 ;;; FUNCTIONS
 
@@ -1071,6 +1103,8 @@ it doesn't interfere with other minibuffer usage.")
 (defun ido-may-cache-directory (&optional dir)
   (setq dir (or dir ido-current-directory))
   (cond
+   ((ido-directory-too-big-p dir)
+    nil)
    ((and (ido-is-root-directory dir)
         (or ido-enable-tramp-completion
             (memq system-type '(windows-nt ms-dos))))
@@ -1340,8 +1374,8 @@ This function also adds a hook to the minibuffer."
     (define-key map "?" 'ido-completion-help)
 
     (when (memq ido-cur-item '(file dir))
-      (define-key map "\C-b" 'ido-enter-switch-buffer)
-      (define-key map "\C-d" 'ido-enter-dired)
+      (define-key map "\C-b" (or ido-context-switch-command 'ido-enter-switch-buffer))
+      (define-key map "\C-d" (or (and ido-context-switch-command 'ignore) 'ido-enter-dired))
       (define-key map "\C-f" 'ido-fallback-command)
       (define-key map [down] 'ido-next-match-dir)
       (define-key map [up]   'ido-prev-match-dir)
@@ -1372,8 +1406,8 @@ This function also adds a hook to the minibuffer."
       )
 
     (when (eq ido-cur-item 'buffer)
+      (define-key map "\C-f" (or ido-context-switch-command 'ido-enter-find-file))
       (define-key map "\C-b" 'ido-fallback-command)
-      (define-key map "\C-f" 'ido-enter-find-file)
       (define-key map "\C-k" 'ido-kill-buffer-at-head)
       )
 
@@ -1414,6 +1448,16 @@ This function also adds a hook to the minibuffer."
         (file-directory-p dir)
         (not (file-readable-p dir)))))
 
+(defun ido-directory-too-big-p (dir)
+  ;; Return t if dir is a directory, but too big to show
+  ;; Do not check for non-readable directories via tramp, as this causes a premature
+  ;; connect on incomplete tramp paths (after entring just method:).
+  (let ((ido-enable-tramp-completion nil))
+    (and (numberp ido-max-directory-size)
+        (ido-final-slash dir)
+        (file-directory-p dir)
+        (> (nth 7 (file-attributes dir)) ido-max-directory-size))))
+
 (defun ido-set-current-directory (dir &optional subdir no-merge)
   ;; Set ido's current directory to DIR or DIR/SUBDIR
   (setq dir (ido-final-slash dir t))
@@ -1428,6 +1472,8 @@ This function also adds a hook to the minibuffer."
     (if (get-buffer ido-completion-buffer)
        (kill-buffer ido-completion-buffer))
     (setq ido-directory-nonreadable (ido-nonreadable-directory-p dir))
+    (setq ido-directory-too-big (and (not ido-directory-nonreadable)
+                                    (ido-directory-too-big-p dir)))
     t))
 
 (defun ido-set-current-home (&optional dir)
@@ -1612,13 +1658,20 @@ If INITIAL is non-nil, it specifies the initial input string."
              ido-rescan nil))
        ((eq ido-cur-item 'file)
        (setq ido-ignored-list nil
-             ido-cur-list (ido-make-file-list ido-default-item)))
+             ido-cur-list (and (not ido-directory-nonreadable)
+                               (not ido-directory-too-big)
+                               (ido-make-file-list ido-default-item))))
        ((eq ido-cur-item 'dir)
        (setq ido-ignored-list nil
-             ido-cur-list (ido-make-dir-list ido-default-item)))
+             ido-cur-list (and (not ido-directory-nonreadable)
+                               (not ido-directory-too-big)
+                               (ido-make-dir-list ido-default-item))))
        ((eq ido-cur-item 'buffer)
        (setq ido-ignored-list nil
              ido-cur-list (ido-make-buffer-list ido-default-item)))
+       ((eq ido-cur-item 'list)
+       (setq ido-ignored-list nil
+             ido-cur-list (ido-make-choice-list ido-default-item)))
        (t nil))
       (setq ido-rotate-temp nil)
 
@@ -1703,7 +1756,7 @@ If INITIAL is non-nil, it specifies the initial input string."
        ((eq ido-exit 'keep)
        (setq ido-keep-item-list t))
 
-       ((memq ido-exit '(dired fallback findfile findbuffer))
+       ((memq ido-exit '(dired fallback find-file switch-to-buffer insert-buffer insert-file))
        (setq done t))
 
        ((eq ido-exit 'updir)
@@ -1719,7 +1772,10 @@ If INITIAL is non-nil, it specifies the initial input string."
            (setq ido-set-default-item t))))
 
        ;; Handling the require-match must be done in a better way.
-       ((and require-match (not (ido-existing-item-p)))
+       ((and require-match
+            (not (if ido-directory-too-big
+                     (file-exists-p (concat ido-current-directory ido-final-text))
+                   (ido-existing-item-p))))
        (error "must specify valid item"))
 
        (t
@@ -1783,19 +1839,26 @@ If INITIAL is non-nil, it specifies the initial input string."
   (exit-minibuffer))
 
 ;;; MAIN FUNCTIONS
-(defun ido-buffer-internal (method &optional fallback prompt default initial)
+(defun ido-buffer-internal (method &optional fallback prompt default initial switch-cmd)
   ;; Internal function for ido-switch-buffer and friends
   (if (not ido-mode)
       (call-interactively (or fallback 'switch-to-buffer))
-    (let ((buf (ido-read-buffer (or prompt "Buffer: ") default nil initial)))
+    (let* ((ido-context-switch-command switch-cmd)
+          (ido-current-directory nil)
+          (ido-directory-nonreadable nil)
+          (ido-directory-too-big nil)
+          (buf (ido-read-internal 'buffer (or prompt "Buffer: ") 'ido-buffer-history default nil initial)))
 
       ;; Choose the buffer name: either the text typed in, or the head
       ;; of the list of matches
 
       (cond
-       ((eq ido-exit 'findfile)
+       ((eq ido-exit 'find-file)
        (ido-file-internal ido-default-file-method nil nil nil nil ido-text))
 
+       ((eq ido-exit 'insert-file)
+       (ido-file-internal 'insert 'insert-file nil "Insert file: " nil ido-text 'ido-enter-insert-buffer))
+
        ((eq ido-exit 'fallback)
        (let ((read-buffer-function nil))
          (call-interactively (or fallback 'switch-to-buffer))))
@@ -1827,18 +1890,6 @@ If INITIAL is non-nil, it specifies the initial input string."
            (set-buffer-major-mode buf))
        (ido-visit-buffer buf method t))))))
 
-;;;###autoload
-(defun ido-read-buffer (prompt &optional default require-match initial)
-  "Replacement for the built-in `read-buffer'.
-Return the name of a buffer selected.
-PROMPT is the prompt to give to the user.  DEFAULT if given is the default
-buffer to be selected, which will go to the front of the list.
-If REQUIRE-MATCH is non-nil, an existing-buffer must be selected.
-If INITIAL is non-nil, it specifies the initial input string."
-  (let ((ido-current-directory nil)
-       (ido-directory-nonreadable nil))
-    (ido-read-internal 'buffer prompt 'ido-buffer-history default require-match initial)))
-
 (defun ido-record-work-directory (&optional dir)
   (when (and (numberp ido-max-work-directory-list) (> ido-max-work-directory-list 0))
     (if (and (setq dir (or dir ido-current-directory)) (> (length dir) 0))
@@ -1880,12 +1931,15 @@ If INITIAL is non-nil, it specifies the initial input string."
   ;; Add final slash to result in case it was missing from DEFAULT-DIRECTORY.
   (ido-final-slash (expand-file-name (or dir default-directory)) t))
 
-(defun ido-file-internal (method &optional fallback default prompt item initial)
+(defun ido-file-internal (method &optional fallback default prompt item initial switch-cmd)
   ;; Internal function for ido-find-file and friends
   (unless item
     (setq item 'file))
   (let* ((ido-current-directory (ido-expand-directory default))
         (ido-directory-nonreadable (ido-nonreadable-directory-p ido-current-directory))
+        (ido-directory-too-big (and (not ido-directory-nonreadable)
+                                    (ido-directory-too-big-p ido-current-directory)))
+        (ido-context-switch-command switch-cmd)
         filename)
 
     (cond
@@ -1937,9 +1991,12 @@ If INITIAL is non-nil, it specifies the initial input string."
              (read-file-name-function nil))
          (call-interactively (or fallback 'find-file))))
 
-       ((eq ido-exit 'findbuffer)
+       ((eq ido-exit 'switch-to-buffer)
        (ido-buffer-internal ido-default-buffer-method nil nil nil ido-text))
 
+       ((eq ido-exit 'insert-buffer)
+       (ido-buffer-internal 'insert 'insert-buffer "Insert buffer: " nil ido-text 'ido-enter-insert-file))
+
        ((eq ido-exit 'dired)
        (dired (concat ido-current-directory (or ido-text ""))))
 
@@ -2056,6 +2113,12 @@ If INITIAL is non-nil, it specifies the initial input string."
          (setq ido-exit 'refresh)
          (exit-minibuffer))))
 
+     (ido-directory-too-big
+      (setq ido-directory-too-big nil)
+      (setq ido-text-init ido-text)
+      (setq ido-exit 'refresh)
+      (exit-minibuffer))
+
      ((not ido-matches)
       (when ido-completion-buffer
        (call-interactively (setq this-command ido-cannot-complete-command))))
@@ -2159,7 +2222,9 @@ If no merge has yet taken place, toggle automatic merging option."
 (defun ido-toggle-ignore ()
   "Toggle ignoring files specified with `ido-ignore-files'."
   (interactive)
-  (setq ido-process-ignore-lists (not ido-process-ignore-lists))
+  (if ido-directory-too-big
+      (setq ido-directory-too-big nil)
+    (setq ido-process-ignore-lists (not ido-process-ignore-lists)))
   (setq ido-text-init ido-text)
   (setq ido-exit 'refresh)
   (exit-minibuffer))
@@ -2215,19 +2280,22 @@ If no buffer or file exactly matching the prompt exists, maybe create a new one.
 (defun ido-fallback-command ()
   "Fallback to non-ido version of current command."
   (interactive)
+  (let ((i (length ido-text)))
+    (while (> i 0)
+      (push (aref ido-text (setq i (1- i))) unread-command-events)))
   (setq ido-exit 'fallback)
   (exit-minibuffer))
 
 (defun ido-enter-find-file ()
   "Drop into find-file from buffer switching."
   (interactive)
-  (setq ido-exit 'findfile)
+  (setq ido-exit 'find-file)
   (exit-minibuffer))
 
 (defun ido-enter-switch-buffer ()
   "Drop into ido-switch-buffer from file switching."
   (interactive)
-  (setq ido-exit 'findbuffer)
+  (setq ido-exit 'switch-to-buffer)
   (exit-minibuffer))
 
 (defun ido-enter-dired ()
@@ -2236,6 +2304,18 @@ If no buffer or file exactly matching the prompt exists, maybe create a new one.
   (setq ido-exit 'dired)
   (exit-minibuffer))
 
+(defun ido-enter-insert-buffer ()
+  "Drop into insert buffer from insert file."
+  (interactive)
+  (setq ido-exit 'insert-buffer)
+  (exit-minibuffer))
+
+(defun ido-enter-insert-file ()
+  "Drop into insert file from insert buffer."
+  (interactive)
+  (setq ido-exit 'insert-file)
+  (exit-minibuffer))
+
 
 (defun ido-up-directory (&optional clear)
   "Go up one directory level."
@@ -2289,6 +2369,7 @@ If no buffer or file exactly matching the prompt exists, maybe create a new one.
               (not (equal dir ido-current-directory))
               (file-directory-p dir)
               (or (not must-match)
+                  ;; TODO. check for nonreadable and too-big.
                   (ido-set-matches1
                    (if (eq ido-cur-item 'file)
                        (ido-make-file-list1 dir)
@@ -2546,7 +2627,8 @@ for first matching file."
 
 (defun ido-all-completions ()
   ;; Return unsorted list of all competions.
-  (let ((ido-process-ignore-lists nil))
+  (let ((ido-process-ignore-lists nil)
+       (ido-directory-too-big nil))
     (cond
      ((eq ido-cur-item 'file)
       (ido-make-file-list1 ido-current-directory))
@@ -2554,13 +2636,74 @@ for first matching file."
       (ido-make-dir-list1 ido-current-directory))
      ((eq ido-cur-item 'buffer)
       (ido-make-buffer-list1))
+     ((eq ido-cur-item 'list)
+      ido-choice-list)
      (t nil))))
 
 
-(defun ido-sort-list (items)
-  ;; Simple list of file or buffer names
-  (sort items (lambda (a b) (string-lessp (ido-no-final-slash a)
-                                         (ido-no-final-slash b)))))
+;; File list sorting
+
+(defun ido-file-lessp (a b)
+  ;; Simple compare two file names.
+  (string-lessp (ido-no-final-slash a) (ido-no-final-slash b)))
+
+
+(defun ido-file-extension-lessp (a b)
+  ;; Compare file names according to ido-file-extensions-order list.
+  (let ((n (compare-strings a 0 nil b 0 nil nil))
+       lessp p)
+    (if (eq n t)
+       nil
+      (if (< n 0)
+         (setq n (1- (- n))
+               p a a b b p
+               lessp t)
+       (setq n (1- n)))
+      (cond
+       ((= n 0)
+       lessp)
+       ((= (aref a n) ?.)
+       (ido-file-extension-aux a b n lessp))
+       (t
+       (while (and (> n 2) (/= (aref a n) ?.))
+         (setq n (1- n)))
+       (if (> n 1)
+           (ido-file-extension-aux a b n lessp)
+         lessp))))))
+
+(defun ido-file-extension-aux (a b n lessp)
+  (let ((oa (ido-file-extension-order a n))
+       (ob (ido-file-extension-order b n)))
+    (cond
+     ((= oa ob)
+      lessp)
+     ((and oa ob)
+      (if lessp
+         (> oa ob)
+       (< oa ob)))
+     (oa
+      (not lessp))
+     (ob
+      lessp)
+     (t
+      lessp))))
+
+(defun ido-file-extension-order (s n)
+  (let ((l ido-file-extensions-order)
+       (i 0) o do)
+    (while l
+      (cond
+       ((eq (car l) t)
+       (setq do i
+             l (cdr l)))
+       ((eq (compare-strings s n nil (car l) 0 nil nil) t)
+       (setq o i
+             l nil))
+       (t
+       (setq l (cdr l))))
+      (setq i (1+ i)))
+    (or o do)))
+
 
 (defun ido-sort-merged-list (items promote)
   ;; Input is list of ("file" . "dir") cons cells.
@@ -2663,6 +2806,7 @@ for first matching file."
                       (or ido-merge-ftp-work-directories
                           (not (ido-is-ftp-directory dir)))
                       (file-directory-p dir)
+                      ;; TODO. check for nonreadable and too-big.
                       (setq fl (if (eq ido-cur-item 'file)
                                    (ido-make-file-list1 dir t)
                                  (ido-make-dir-list1 dir t))))
@@ -2716,6 +2860,20 @@ for first matching file."
     (run-hooks 'ido-make-buffer-list-hook)
     ido-temp-list))
 
+(defun ido-make-choice-list (default)
+  ;; Return the current list of choices.
+  ;; If DEFAULT is non-nil, and corresponds to an element of choices,
+  ;; it is put to the start of the list.
+  (let ((ido-temp-list ido-choice-list))
+    (if default
+       (progn
+         (setq ido-temp-list
+               (delete default ido-temp-list))
+         (setq ido-temp-list
+               (cons default ido-temp-list))))
+    ; (run-hooks 'ido-make-choice-list-hook)
+    ido-temp-list))
+
 (defun ido-to-end (items)
   ;; Move the elements from ITEMS to the end of `ido-temp-list'
   (mapcar
@@ -2729,6 +2887,8 @@ for first matching file."
 (defun ido-file-name-all-completions1 (dir)
   (cond
    ((ido-nonreadable-directory-p dir) '())
+   ;; do not check (ido-directory-too-big-p dir) here.
+   ;; Caller must have done that if necessary.
    ((and ido-enable-tramp-completion
         (string-match "\\`/\\([^/:]+:\\([^/:@]+@\\)?\\)\\'" dir))
 
@@ -2816,7 +2976,10 @@ for first matching file."
   ;; created to allow the user to further modify the order of the file names
   ;; in this list.
   (let ((ido-temp-list (ido-make-file-list1 ido-current-directory)))
-    (setq ido-temp-list (ido-sort-list ido-temp-list))
+    (setq ido-temp-list (sort ido-temp-list
+                             (if ido-file-extensions-order
+                                 #'ido-file-extension-lessp
+                               #'ido-file-lessp)))
     (let ((default-directory ido-current-directory))
       (ido-to-end ;; move ftp hosts and visited files to end
        (delq nil (mapcar
@@ -2865,7 +3028,7 @@ for first matching file."
   ;; created to allow the user to further modify the order of the
   ;; directory names in this list.
   (let ((ido-temp-list (ido-make-dir-list1 ido-current-directory)))
-    (setq ido-temp-list (ido-sort-list ido-temp-list))
+    (setq ido-temp-list (sort ido-temp-list #'ido-file-lessp))
     (ido-to-end  ;; move . files to end
      (delq nil (mapcar
                (lambda (x) (if (string-equal (substring x 0 1) ".") x))
@@ -2928,13 +3091,22 @@ for first matching file."
                       (concat "\\`" re "\\'")))
         (prefix-re (and full-re (not ido-enable-prefix)
                         (concat "\\`" rexq)))
+        (non-prefix-dot (or (not ido-enable-dot-prefix)
+                            (not ido-process-ignore-lists)
+                            ido-enable-prefix
+                            (= (length ido-text) 0)))
+
         full-matches
         prefix-matches
         matches)
     (mapcar
      (lambda (item)
        (let ((name (ido-name item)))
-        (if (string-match re name)
+        (if (and (or non-prefix-dot
+                     (if (= (aref ido-text 0) ?.)
+                         (= (aref name 0) ?.)
+                       (/= (aref name 0) ?.)))
+                 (string-match re name))
             (cond
              ((and full-re (string-match full-re name))
               (setq full-matches (cons item full-matches)))
@@ -3086,14 +3258,15 @@ for first matching file."
       (setq display-it t))
     (if display-it
        (with-output-to-temp-buffer ido-completion-buffer
-         (let ((completion-list (ido-sort-list
+         (let ((completion-list (sort
                                  (cond
                                   (ido-use-merged-list
                                    (ido-flatten-merged-list (or ido-matches ido-cur-list)))
                                   ((or full-list ido-completion-buffer-all-completions)
                                    (ido-all-completions))
                                   (t
-                                   (copy-sequence (or ido-matches ido-cur-list)))))))
+                                   (copy-sequence (or ido-matches ido-cur-list))))
+                                 #'ido-file-lessp)))
            (if (featurep 'xemacs)
                ;; XEmacs extents are put on by default, doesn't seem to be
                ;; any way of switching them off.
@@ -3262,7 +3435,7 @@ For details of keybindings, do `\\[describe-function] ido'."
 The buffer name is selected interactively by typing a substring.
 For details of keybindings, do `\\[describe-function] ido'."
   (interactive)
-  (ido-buffer-internal 'display 'display-buffer))
+  (ido-buffer-internal 'display 'display-buffer nil nil nil 'ignore))
 
 ;;;###autoload
 (defun ido-kill-buffer ()
@@ -3270,7 +3443,7 @@ For details of keybindings, do `\\[describe-function] ido'."
 The buffer name is selected interactively by typing a substring.
 For details of keybindings, do `\\[describe-function] ido'."
   (interactive)
-  (ido-buffer-internal 'kill 'kill-buffer "Kill buffer: " (buffer-name (current-buffer))))
+  (ido-buffer-internal 'kill 'kill-buffer "Kill buffer: " (buffer-name (current-buffer)) nil 'ignore))
 
 ;;;###autoload
 (defun ido-insert-buffer ()
@@ -3278,7 +3451,7 @@ For details of keybindings, do `\\[describe-function] ido'."
 The buffer name is selected interactively by typing a substring.
 For details of keybindings, do `\\[describe-function] ido'."
   (interactive)
-  (ido-buffer-internal 'insert 'insert-buffer "Insert buffer: "))
+  (ido-buffer-internal 'insert 'insert-buffer "Insert buffer: " nil nil 'ido-enter-insert-file))
 
 ;;;###autoload
 (defun ido-switch-buffer-other-frame ()
@@ -3296,7 +3469,7 @@ For details of keybindings, do `\\[describe-function] ido'."
   (interactive "DDir: ")
   (if (not (equal (substring dir -1) "/"))
       (setq dir (concat dir "/")))
-  (ido-file-internal ido-default-file-method nil dir))
+  (ido-file-internal ido-default-file-method nil dir nil nil nil 'ignore))
 
 ;;;###autoload
 (defun ido-find-file ()
@@ -3389,7 +3562,7 @@ For details of keybindings, do `\\[describe-function] ido-find-file'."
 The file name is selected interactively by typing a substring.
 For details of keybindings, do `\\[describe-function] ido-find-file'."
   (interactive)
-  (ido-file-internal 'display))
+  (ido-file-internal 'display nil nil nil nil nil 'ignore))
 
 ;;;###autoload
 (defun ido-find-file-other-frame ()
@@ -3411,7 +3584,7 @@ For details of keybindings, do `\\[describe-function] ido-find-file'."
        (ido-report-no-match nil)
        (ido-confirm-unique-completion t)
        (ido-auto-merge-work-directories-length -1))
-    (ido-file-internal 'write 'write-file nil "Write file: ")))
+    (ido-file-internal 'write 'write-file nil "Write file: " nil nil 'ignore)))
 
 ;;;###autoload
 (defun ido-insert-file ()
@@ -3419,7 +3592,7 @@ For details of keybindings, do `\\[describe-function] ido-find-file'."
 The file name is selected interactively by typing a substring.
 For details of keybindings, do `\\[describe-function] ido-find-file'."
   (interactive)
-  (ido-file-internal 'insert 'insert-file nil "Insert file: "))
+  (ido-file-internal 'insert 'insert-file nil "Insert file: " nil nil 'ido-enter-insert-buffer))
 
 ;;;###autoload
 (defun ido-dired ()
@@ -3500,7 +3673,7 @@ For details of keybindings, do `\\[describe-function] ido-find-file'."
 
        ;; Handle explicit directory changes
        (cond
-        ((eq ido-cur-item 'buffer)
+        ((memq ido-cur-item '(buffer list))
          )
 
         ((= (length contents) 0)
@@ -3556,7 +3729,7 @@ For details of keybindings, do `\\[describe-function] ido-find-file'."
                 (expand-file-name "/" ido-current-directory)
               "/"))
            (setq refresh t))
-          ((and ido-directory-nonreadable
+          ((and (or ido-directory-nonreadable ido-directory-too-big)
                 (file-directory-p (concat ido-current-directory (file-name-directory contents))))
            (ido-set-current-directory
             (concat ido-current-directory (file-name-directory contents)))
@@ -3618,6 +3791,7 @@ For details of keybindings, do `\\[describe-function] ido-find-file'."
 
        (when (and (not ido-matches)
                   (not ido-directory-nonreadable)
+                  (not ido-directory-too-big)
                   ;; ido-rescan ?
                   ido-process-ignore-lists
                   ido-ignored-list)
@@ -3641,7 +3815,8 @@ For details of keybindings, do `\\[describe-function] ido-find-file'."
               (not (ido-is-root-directory))
               (> (length contents) 1)
               (not (string-match "[$]" contents))
-              (not ido-directory-nonreadable))
+              (not ido-directory-nonreadable)
+              (not ido-directory-too-big))
          (ido-trace "merge?")
          (if ido-use-merged-list
              (ido-undo-merge-work-directory contents nil)
@@ -3706,6 +3881,8 @@ For details of keybindings, do `\\[describe-function] ido-find-file'."
           (cond
            (ido-directory-nonreadable
             (or (nth 8 ido-decorations) " [Not readable]"))
+           (ido-directory-too-big
+            (or (nth 9 ido-decorations) " [Too big]"))
            (ido-report-no-match
             (nth 6 ido-decorations))  ;; [No match]
            (t "")))
@@ -3811,42 +3988,76 @@ For details of keybindings, do `\\[describe-function] ido-find-file'."
 
 (put 'dired-do-rename 'ido 'ignore)
 
+;;;###autoload
+(defun ido-read-buffer (prompt &optional default require-match)
+  "Ido replacement for the built-in `read-buffer'.
+Return the name of a buffer selected.
+PROMPT is the prompt to give to the user.  DEFAULT if given is the default
+buffer to be selected, which will go to the front of the list.
+If REQUIRE-MATCH is non-nil, an existing-buffer must be selected."
+  (let* ((ido-current-directory nil)
+        (ido-directory-nonreadable nil)
+        (ido-directory-too-big nil)
+        (ido-context-switch-command 'ignore)
+        (buf (ido-read-internal 'buffer prompt 'ido-buffer-history default require-match)))
+    (if (eq ido-exit 'fallback)
+       (let ((read-buffer-function nil))
+         (read-buffer prompt default require-match))
+      buf)))
+
 ;;;###autoload
 (defun ido-read-file-name (prompt &optional dir default-filename mustmatch initial predicate)
-  "Read file name, prompting with PROMPT and completing in directory DIR.
+  "Ido replacement for the built-in `read-file-name'.
+Read file name, prompting with PROMPT and completing in directory DIR.
 See `read-file-name' for additional parameters."
-  (cond
-  ((or (eq predicate 'file-directory-p)
-       (eq (get this-command 'ido) 'dir)
-       (memq this-command ido-read-file-name-as-directory-commands))
-   (ido-read-directory-name prompt dir default-filename mustmatch initial))
-  ((and (not (eq (get this-command 'ido) 'ignore))
-       (not (memq this-command ido-read-file-name-non-ido))
-       (or (null predicate) (eq predicate 'file-exists-p)))
-   (let* (filename
-         ido-saved-vc-hb
-         (vc-handled-backends (and (boundp 'vc-handled-backends) vc-handled-backends))
-         (ido-current-directory (ido-expand-directory dir))
-         (ido-directory-nonreadable (not (file-readable-p ido-current-directory)))
-         (ido-work-directory-index -1)
-         (ido-work-file-index -1)
-         (ido-find-literal nil))
-     (setq filename
-          (ido-read-internal 'file prompt 'ido-file-history default-filename mustmatch initial))
-     (if filename
-        (concat ido-current-directory filename))))
-  (t
-   (let ((read-file-name-function nil))
-     (read-file-name prompt dir default-filename mustmatch initial predicate)))))
+  (let (filename)
+    (cond
+     ((or (eq predicate 'file-directory-p)
+         (eq (get this-command 'ido) 'dir)
+         (memq this-command ido-read-file-name-as-directory-commands))
+      (setq filename
+           (ido-read-directory-name prompt dir default-filename mustmatch initial)))
+     ((and (not (eq (get this-command 'ido) 'ignore))
+          (not (memq this-command ido-read-file-name-non-ido))
+          (or (null predicate) (eq predicate 'file-exists-p)))
+      (let* (ido-saved-vc-hb
+            (ido-context-switch-command 'ignore)
+            (vc-handled-backends (and (boundp 'vc-handled-backends) vc-handled-backends))
+            (ido-current-directory (ido-expand-directory dir))
+            (ido-directory-nonreadable (not (file-readable-p ido-current-directory)))
+            (ido-directory-too-big (and (not ido-directory-nonreadable)
+                                        (ido-directory-too-big-p ido-current-directory)))
+            (ido-work-directory-index -1)
+            (ido-work-file-index -1)
+            (ido-find-literal nil))
+       (setq ido-exit nil)
+       (setq filename
+             (ido-read-internal 'file prompt 'ido-file-history default-filename mustmatch initial))
+       (cond
+        ((eq ido-exit 'fallback)
+         (setq filename 'fallback))
+        (filename
+         (setq filename
+               (concat ido-current-directory filename))))))
+     (t
+      (setq filename 'fallback)))
+    (if (eq filename 'fallback)
+       (let ((read-file-name-function nil))
+         (read-file-name prompt dir default-filename mustmatch initial predicate))
+      filename)))
 
 ;;;###autoload
 (defun ido-read-directory-name (prompt &optional dir default-dirname mustmatch initial)
-  "Read directory name, prompting with PROMPT and completing in directory DIR.
-See `read-file-name' for additional parameters."
+  "Ido replacement for the built-in `read-directory-name'.
+Read directory name, prompting with PROMPT and completing in directory DIR.
+See `read-directory-name' for additional parameters."
   (let* (filename
+        (ido-context-switch-command 'ignore)
         ido-saved-vc-hb
         (ido-current-directory (ido-expand-directory dir))
         (ido-directory-nonreadable (not (file-readable-p ido-current-directory)))
+        (ido-directory-too-big (and (not ido-directory-nonreadable)
+                                    (ido-directory-too-big-p ido-current-directory)))
         (ido-work-directory-index -1)
         (ido-work-file-index -1))
     (setq filename
@@ -3856,5 +4067,29 @@ See `read-file-name' for additional parameters."
            ido-current-directory
          (concat ido-current-directory filename)))))
 
+;;;###autoload
+(defun ido-completing-read (prompt choices &optional predicate require-match initial-input hist def)
+  "Ido replacement for the built-in `completing-read'.
+Read a string in the minibuffer with ido-style completion.
+PROMPT is a string to prompt with; normally it ends in a colon and a space.
+CHOICES is a list of strings which are the possible completions.
+PREDICATE is currently ignored; it is included to be compatible
+ with `completing-read'.
+If REQUIRE-MATCH is non-nil, the user is not allowed to exit unless
+ the input is (or completes to) an element of CHOICES or is null.
+ If the input is null, `ido-completing-read' returns DEF, or an empty
+ string if DEF is nil, regardless of the value of REQUIRE-MATCH.
+If INITIAL-INPUT is non-nil, insert it in the minibuffer initially,
+ with point positioned at the end.
+HIST, if non-nil, specifies a history list.
+DEF, if non-nil, is the default value."
+  (let ((ido-current-directory nil)
+       (ido-directory-nonreadable nil)
+       (ido-directory-too-big nil)
+       (ido-context-switch-command 'ignore)
+       (ido-choice-list choices))
+    (ido-read-internal 'list prompt hist def require-match initial-input)))
+
+
 ;;; arch-tag: b63a3500-1735-41bd-8a01-05373f0864da
 ;;; ido.el ends here