*** empty log message ***
[bpt/emacs.git] / lisp / ido.el
index e6dcea5..64ddf76 100644 (file)
@@ -1,7 +1,7 @@
 ;;; ido.el --- interactively do things with buffers and files.
 
 ;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
-;;   2004, 2005 Free Software Foundation, Inc.
+;;   2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 
 ;; Author: Kim F. Storm <storm@cua.dk>
 ;; Based on: iswitchb by Stephen Eglen <stephen@cns.ed.ac.uk>
@@ -11,7 +11,7 @@
 
 ;; GNU Emacs is free software; you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
+;; the Free Software Foundation; either version 3, or (at your option)
 ;; any later version.
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 ;; Boston, MA 02110-1301, USA.
 
-;;; Acknowledgements
-
-;; Infinite amounts of gratitude goes to Stephen Eglen <stephen@cns.ed.ac.uk>
-;; who wrote iswitch-buffer mode - from which I ripped off 99% of the code
-;; for ido-switch-buffer and found the inspiration for ido-find-file.
-;; The ido package would never have existed without his work.
-
-;; Also thanks to Klaus Berndl, Rohit Namjoshi, Robert Fenk, Alex
-;; Schroeder, Bill Benedetto, Stephen Eglen, and many others for bug
-;; fixes and improvements.
-
-;;; History
-
-;; Since I discovered Stephen Eglen's excellent iswitchb package, I just
-;; couldn't live without it, but once being addicted to switching buffers
-;; with a minimum of keystrokes, I soon found that opening files in the
-;; old-fashioned way was just too slow - so I decided to write a package
-;; which could open files with the same speed and ease as iswitchb could
-;; switch buffers.
-
-;; I originally wrote a separate ifindf.el package based on a copy of
-;; iswitchb.el, which did for opening files what iswitchb did for
-;; switching buffers.  Along the way, I corrected a few errors in
-;; ifindf which could have found its way back into iswitchb, but since
-;; most of the functionality of the two package was practically
-;; identical, I decided that the proper thing to do was to merge my
-;; ifindf package back into iswitchb.
-;;
-;; This is basically what ido (interactively do) is all about; but I
-;; found it ackward to merge my changes into the "iswitchb-" namespace,
-;; so I invented a common "ido-" namespace for the merged packages.
-;;
-;; This version is based on ido.el version 1.57 released on
-;; gnu.emacs.sources adapted for emacs 22.1 to use command remapping
-;; and optionally hooking the read-buffer and read-file-name functions.
-;;
-;; Prefix matching was added by Klaus Berndl <klaus.berndl@sdm.de> based on
-;; an idea of Yuji Minejima <ggb01164@nifty.ne.jp> and his mcomplete-package.
-
 
 ;;; Commentary:
 
 ;; most recent, when I use ido-switch-buffer, I first of all get
 ;; presented with the list of all the buffers
 ;;
-;;       Buffer:  {123456,123}
+;;       Buffer: {123456 | 123}
 ;;
 ;; If I then press 2:
-;;       Buffer: 2[3]{123456,123}
+;;       Buffer: 2[3]{123456 | 123}
 ;;
 ;; The list in {...} are the matching buffers, most recent first
 ;; (buffers visible in the current frame are put at the end of the
 ;; pressing TAB.  In this case, I will get "3" added to my input.
 
 ;; So, I press TAB:
-;;      Buffer: 23{123456,123}
+;;      Buffer: 23{123456 | 123}
 ;;
 ;; At this point, I still have two matching buffers.
 ;; If I want the first buffer in the list, I simply press RET.  If I
 ;; top of the list and then RET to select it.
 ;;
 ;; However, if I type 4, I only have one match left:
-;;       Buffer: 234[123456] [Matched]
+;;       Buffer: 234[123456]
+;;
+;; Since there is only one matching buffer left, it is given in [] and
+;; it is shown in the `ido-only-match' face (ForestGreen).  I can now
+;; press TAB or RET to go to that buffer.
 ;;
-;; Since there is only one matching buffer left, it is given in [] and we
-;; see the text [Matched] afterwards.  I can now press TAB or RET to go
-;; to that buffer.
+;; If I want to create a new buffer named "234", I press C-j instead of
+;; TAB or RET.
 ;;
-;; If however, I now type "a":
+;; If instead, I type "a":
 ;;       Buffer: 234a [No match]
 ;; There are no matching buffers.  If I press RET or TAB, I can be
 ;; prompted to create a new buffer called "234a".
 ;; can be used by other packages to read a buffer name, a file name,
 ;; or a directory name in the `ido' way.
 
+;;; Acknowledgements
+
+;; Infinite amounts of gratitude goes to Stephen Eglen <stephen@cns.ed.ac.uk>
+;; who wrote iswitch-buffer mode - from which I ripped off 99% of the code
+;; for ido-switch-buffer and found the inspiration for ido-find-file.
+;; The ido package would never have existed without his work.
+
+;; Also thanks to Klaus Berndl, Rohit Namjoshi, Robert Fenk, Alex
+;; Schroeder, Bill Benedetto, Stephen Eglen, and many others for bug
+;; fixes and improvements.
+
+;;; History
+
+;; Since I discovered Stephen Eglen's excellent iswitchb package, I just
+;; couldn't live without it, but once being addicted to switching buffers
+;; with a minimum of keystrokes, I soon found that opening files in the
+;; old-fashioned way was just too slow - so I decided to write a package
+;; which could open files with the same speed and ease as iswitchb could
+;; switch buffers.
+
+;; I originally wrote a separate ifindf.el package based on a copy of
+;; iswitchb.el, which did for opening files what iswitchb did for
+;; switching buffers.  Along the way, I corrected a few errors in
+;; ifindf which could have found its way back into iswitchb, but since
+;; most of the functionality of the two package was practically
+;; identical, I decided that the proper thing to do was to merge my
+;; ifindf package back into iswitchb.
+;;
+;; This is basically what ido (interactively do) is all about; but I
+;; found it ackward to merge my changes into the "iswitchb-" namespace,
+;; so I invented a common "ido-" namespace for the merged packages.
+;;
+;; This version is based on ido.el version 1.57 released on
+;; gnu.emacs.sources adapted for emacs 22.1 to use command remapping
+;; and optionally hooking the read-buffer and read-file-name functions.
+;;
+;; Prefix matching was added by Klaus Berndl <klaus.berndl@sdm.de> based on
+;; an idea of Yuji Minejima <ggb01164@nifty.ne.jp> and his mcomplete-package.
+
 
 ;;; Code:
 
@@ -357,7 +360,10 @@ use either \\[customize] or the function `ido-mode'."
   :initialize 'custom-initialize-set
   :require 'ido
   :link '(emacs-commentary-link "ido.el")
-  :set-after '(ido-save-directory-list-file)
+  :set-after '(ido-save-directory-list-file
+              ;; This will clear ido-unc-hosts-cache, so set it
+              ;; before loading history file.
+              ido-unc-hosts)
   :type '(choice (const :tag "Turn on only buffer" buffer)
                  (const :tag "Turn on only file" file)
                  (const :tag "Turn on both buffer and file" both)
@@ -398,13 +404,13 @@ example functions that filter filenames."
   :group 'ido)
 
 (defcustom ido-ignore-extensions t
-  "*Non-nil means ignore files in completion-ignored-extensions list."
+  "*Non-nil means ignore files in `completion-ignored-extensions' list."
   :type 'boolean
   :group 'ido)
 
 (defcustom ido-show-dot-for-dired nil
   "*Non-nil means to always put . as the first item in file name lists.
-This allows the current directory to be opened immediate with `dired'."
+This allows the current directory to be opened immediately with `dired'."
   :type 'boolean
   :group 'ido)
 
@@ -442,35 +448,41 @@ in merged file and directory lists."
 ;;; Examples for setting the value of ido-ignore-files
 ;(setq ido-ignore-files '("^ " "\\.c$" "\\.h$"))
 
-(defcustom ido-default-file-method  'always-frame
-    "*How to switch to new file when using `ido-find-file'.
+(defcustom ido-default-file-method  'raise-frame
+  "*How to visit a new file when using `ido-find-file'.
 Possible values:
-`samewindow'   Show new file in same window
-`otherwindow'  Show new file in another window (same frame)
-`display'      Display file in another window without switching to it
-`otherframe'   Show new file in another frame
-`maybe-frame'  If a file is visible in another frame, prompt to ask if you
-               you want to see the file in the same window of the current
-               frame or in the other frame
-`always-frame'  If a file is visible in another frame, raise that
-               frame; otherwise, visit the file in the same window"
-    :type '(choice (const samewindow)
-                  (const otherwindow)
-                  (const display)
-                  (const otherframe)
-                  (const maybe-frame)
-                  (const always-frame))
+`selected-window' Show new file in selected window
+`other-window'   Show new file in another window (same frame)
+`display'        Display file in another window without selecting to it
+`other-frame'    Show new file in another frame
+`maybe-frame'    If a file is visible in another frame, prompt to ask if you
+                 you want to see the file in the same window of the current
+                 frame or in the other frame
+`raise-frame'     If a file is visible in another frame, raise that
+                 frame; otherwise, visit the file in the same window"
+    :type '(choice (const :tag "Visit in selected window" selected-window)
+                  (const :tag "Visit in other window" other-window)
+                  (const :tag "Display (no select) in other window" display)
+                  (const :tag "Visit in other frame" other-frame)
+                  (const :tag "Ask to visit in other frame" maybe-frame)
+                  (const :tag "Raise frame if already visited" raise-frame))
     :group 'ido)
 
-(defcustom ido-default-buffer-method  'always-frame
-    "*How to switch to new buffer when using `ido-switch-buffer'.
+(defcustom ido-default-buffer-method  'raise-frame
+  "*How to switch to new buffer when using `ido-switch-buffer'.
 See `ido-default-file-method' for details."
-    :type '(choice (const samewindow)
-                  (const otherwindow)
+    :type '(choice (const :tag "Show in selected window" selected-window)
+                  (const :tag "Show in other window" other-window)
+                  (const :tag "Display (no select) in other window" display)
+                  (const :tag "Show in other frame" other-frame)
+                  (const :tag "Ask to show in other frame" maybe-frame)
+                  (const :tag "Raise frame if already shown" raise-frame))
+    :type '(choice (const selected-window)
+                  (const other-window)
                   (const display)
-                  (const otherframe)
+                  (const other-frame)
                   (const maybe-frame)
-                  (const always-frame))
+                  (const raise-frame))
     :group 'ido)
 
 (defcustom ido-enable-flex-matching nil
@@ -491,7 +503,7 @@ Value can be toggled within `ido' using `ido-toggle-regexp'."
 (defcustom ido-enable-prefix nil
   "*Non-nil means only match if the entered text is a prefix of file name.
 This behavior is like the standard emacs-completion.
-Nil means to match if the entered text is an arbitrary substring.
+If nil, match if the entered text is an arbitrary substring.
 Value can be toggled within `ido' using `ido-toggle-prefix'."
   :type 'boolean
   :group 'ido)
@@ -610,6 +622,7 @@ A tramp file name uses the following syntax: /method:user@host:filename."
 
 (defcustom ido-cache-ftp-work-directory-time 1.0
   "*Maximum time to cache contents of an ftp directory (in hours).
+Use C-l in prompt to refresh list.
 If zero, ftp directories are not cached."
   :type 'number
   :group 'ido)
@@ -626,10 +639,44 @@ equivalent function, e.g. `find-file' rather than `ido-find-file'."
   :type '(repeat regexp)
   :group 'ido)
 
+(defvar ido-unc-hosts-cache t
+  "Cached value from `ido-unc-hosts' function.")
+
+(defcustom ido-unc-hosts nil
+  "*List of known UNC host names to complete after initial //.
+If value is a function, that function is called to search network for
+hosts on first use of UNC path."
+  :type '(choice (repeat :tag "List of UNC host names" string)
+                (function-item :tag "Use `NET VIEW'"
+                               :value ido-unc-hosts-net-view)
+                (function :tag "Your own function"))
+  :set #'(lambda (symbol value)
+          (set symbol value)
+          (setq ido-unc-hosts-cache t))
+  :group 'ido)
+
+(defcustom ido-downcase-unc-hosts t
+  "*Non-nil if UNC host names should be downcased."
+  :type 'boolean
+  :group 'ido)
+
+(defcustom ido-ignore-unc-host-regexps nil
+  "*List of regexps matching UNC hosts to ignore.
+Case is ignored if `ido-downcase-unc-hosts' is set."
+  :type '(repeat regexp)
+  :group 'ido)
+
+(defcustom ido-cache-unc-host-shares-time 8.0
+  "*Maximum time to cache shares of an UNC host (in hours).
+Use C-l in prompt to refresh list.
+If zero, UNC host shares are not cached."
+  :type 'number
+  :group 'ido)
+
 (defcustom ido-max-work-file-list 10
   "*Maximum number of names of recently opened files to record.
 This is the list the file names (sans directory) which have most recently
-been opened. See `ido-work-file-list' and `ido-save-directory-list-file'."
+been opened.  See `ido-work-file-list' and `ido-save-directory-list-file'."
   :type 'integer
   :group 'ido)
 
@@ -667,7 +714,7 @@ When a (partial) file name matches this regexp, merging is inhibited."
 
 (defcustom ido-max-dir-file-cache 100
   "*Maximum number of working directories to be cached.
-This is the size of the cache of file-name-all-completions results.
+This is the size of the cache of `file-name-all-completions' results.
 Each cache entry is time stamped with the modification time of the
 directory.  Some systems, like Windows, have unreliable directory
 modification times, so you may choose to disable caching on such
@@ -730,7 +777,7 @@ Obsolete.  Set 3rd element of `ido-decorations' instead."
   "*List of strings used by ido to display the alternatives in the minibuffer.
 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),
+3rd element is the separator between prospects (ignored if `ido-separator' is set),
 4th element is the string inserted at the end of a truncated list of prospects,
 5th and 6th elements are used as brackets around the common match string which
 can be completed using TAB,
@@ -748,13 +795,13 @@ subdirs in the alternatives."
   :group 'ido)
 
 (defface ido-first-match  '((t (:bold t)))
-  "*Font used by ido for highlighting first match."
+  "*Face used by ido for highlighting first match."
   :group 'ido)
 
 (defface ido-only-match  '((((class color))
                                  (:foreground "ForestGreen"))
                                 (t (:italic t)))
-  "*Font used by ido for highlighting only match."
+  "*Face used by ido for highlighting only match."
   :group 'ido)
 
 (defface ido-subdir  '((((min-colors 88) (class color))
@@ -762,7 +809,7 @@ subdirs in the alternatives."
                            (((class color))
                              (:foreground "red"))
                             (t (:underline t)))
-  "*Font used by ido for highlighting subdirs in the alternatives."
+  "*Face used by ido for highlighting subdirs in the alternatives."
   :group 'ido)
 
 (defface ido-indicator  '((((min-colors 88) (class color))
@@ -774,7 +821,7 @@ subdirs in the alternatives."
                                 :background "red"
                                 :width condensed))
                               (t (:inverse-video t)))
-  "*Font used by ido for highlighting its indicators."
+  "*Face used by ido for highlighting its indicators."
   :group 'ido)
 
 (defface ido-incomplete-regexp
@@ -817,7 +864,7 @@ variables:
   prefix    - either nil or a fixed prefix for the dirname
 
 The following variables are available, but should not be changed:
-  ido-current-directory - the unabbreviated directory name
+  `ido-current-directory' - the unabbreviated directory name
   item - equals `file' or `dir' depending on the current mode."
   :type 'hook
   :group 'ido)
@@ -851,7 +898,7 @@ See documentation of `walk-windows' for useful values.")
 (defcustom ido-minibuffer-setup-hook nil
   "*Ido-specific customization of minibuffer setup.
 
-This hook is run during minibuffer setup iff `ido' will be active.
+This hook is run during minibuffer setup if `ido' is active.
 It is intended for use in customizing ido for interoperation
 with other packages.  For instance:
 
@@ -875,7 +922,7 @@ Must be set before enabling ido mode."
   :group 'ido)
 
 (defcustom ido-read-file-name-as-directory-commands '()
-  "List of commands which uses read-file-name to read a directory name.
+  "List of commands which uses `read-file-name' to read a directory name.
 When `ido-everywhere' is non-nil, the commands in this list will read
 the directory using `ido-read-directory-name'."
   :type '(repeat symbol)
@@ -972,7 +1019,7 @@ Copied from `icomplete-eoinput'.")
   "List of files currently matching `ido-text'.")
 
 (defvar ido-report-no-match t
-  "Report [No Match] when no completions matches ido-text.")
+  "Report [No Match] when no completions matches `ido-text'.")
 
 (defvar ido-exit nil
   "Flag to monitor how `ido-find-file' exits.
@@ -987,18 +1034,25 @@ selected.")
 
 (defvar ido-use-mycompletion-depth 0
   "Non-nil means use `ido' completion feedback.
-Is set by ido functions to the current minibuffer-depth, so that
-it doesn't interfere with other minibuffer usage.")
+Is set by ido functions to the current `minibuffer-depth',
+so that it doesn't interfere with other minibuffer usage.")
 
 (defvar ido-incomplete-regexp nil
   "Non-nil if an incomplete regexp is entered.")
 
+(defvar ido-initial-position nil
+  "Non-nil means to explicitly cursor on entry to minibuffer.
+Value is an integer which is number of chars to right of prompt.")
+
 ;;; Variables with dynamic bindings.
 ;;; Declared here to keep the byte compiler quiet.
 
 ;; Stores the current ido item type ('file, 'dir, 'buffer, or 'list).
 (defvar ido-cur-item)
 
+;;; Stores the current default item
+(defvar ido-default-item)
+
 ;; Stores the current list of items that will be searched through.
 ;; The list is ordered, so that the most interesting item comes first,
 ;; although by default, the files visible in the current frame are put
@@ -1069,7 +1123,9 @@ it doesn't interfere with other minibuffer usage.")
 (defun ido-active (&optional merge)
   (if merge
       ido-use-merged-list
-    (and (boundp 'ido-completing-read) (= ido-use-mycompletion-depth (minibuffer-depth)))))
+    (and (boundp 'ido-completing-read)
+        (or (featurep 'xemacs)
+            (= ido-use-mycompletion-depth (minibuffer-depth))))))
 
 (defvar ido-trace-enable nil)
 
@@ -1095,11 +1151,73 @@ it doesn't interfere with other minibuffer usage.")
          (pop-to-buffer b t t)
          (setq truncate-lines t)))))
 
+(defun ido-local-file-exists-p (file)
+  "Tell if FILE exists locally."
+  (let (file-name-handler-alist)
+    (file-exists-p file)))
+
+(defun ido-unc-hosts (&optional query)
+  "Return list of UNC host names."
+  (let ((hosts
+        (cond
+         ((listp ido-unc-hosts)
+          ido-unc-hosts)               ;; static list or nil
+         ((listp ido-unc-hosts-cache)
+          ido-unc-hosts-cache) ;; result of net search
+         ((and query (fboundp ido-unc-hosts))
+          (message (propertize "Searching for UNC hosts..." 'face 'highlight))
+          (setq ido-unc-hosts-cache (funcall ido-unc-hosts))
+          (message nil)
+          ido-unc-hosts-cache)
+         (query
+          (setq ido-unc-hosts-cache nil))
+         (t (fboundp ido-unc-hosts)))))
+    (when query
+      (let ((case-fold-search ido-downcase-unc-hosts)
+           res host re-list re)
+       (while hosts
+         (setq host (car hosts)
+               hosts (cdr hosts)
+               re-list (and ido-process-ignore-lists
+                            ido-ignore-unc-host-regexps))
+         (while re-list
+           (setq re (car re-list)
+                 re-list (cdr re-list))
+           (if (string-match re host)
+               (setq re-list nil
+                     host nil)))
+         (when host
+           (when ido-downcase-unc-hosts
+             (setq host (downcase host)))
+           (setq res (cons host res))))
+       (setq hosts (sort res #'string<))))
+    hosts))
+
+(defun ido-unc-hosts-net-view ()
+  "Query network for list of UNC host names using `NET VIEW'."
+  (let (hosts)
+    (with-temp-buffer
+      (shell-command "net view" t)
+      (goto-char (point-min))
+      (while (re-search-forward "^\\\\\\\\\\([[:graph:]]+\\)" nil t)
+       (setq hosts (cons (match-string 1) hosts))))
+    hosts))
+
 (defun ido-is-tramp-root (&optional dir)
   (and ido-enable-tramp-completion
        (string-match "\\`/[^/]+[@:]\\'"
                     (or dir ido-current-directory))))
 
+(defun ido-is-unc-root (&optional dir)
+  (and (ido-unc-hosts)
+       (string-equal "//"
+                    (or dir ido-current-directory))))
+
+(defun ido-is-unc-host (&optional dir)
+  (and (ido-unc-hosts)
+       (string-match "\\`//[^/]+/\\'"
+                    (or dir ido-current-directory))))
+
 (defun ido-is-root-directory (&optional dir)
   (setq dir (or dir ido-current-directory))
   (or
@@ -1145,6 +1263,12 @@ it doesn't interfere with other minibuffer usage.")
        (or (not time)
           (< (- (ido-time-stamp) time) ido-cache-ftp-work-directory-time))))
 
+(defun ido-cache-unc-valid (&optional time)
+  (and (numberp ido-cache-unc-host-shares-time)
+       (> ido-cache-unc-host-shares-time 0)
+       (or (not time)
+          (< (- (ido-time-stamp) time) ido-cache-unc-host-shares-time))))
+
 (defun ido-may-cache-directory (&optional dir)
   (setq dir (or dir ido-current-directory))
   (cond
@@ -1154,10 +1278,11 @@ it doesn't interfere with other minibuffer usage.")
         (or ido-enable-tramp-completion
             (memq system-type '(windows-nt ms-dos))))
     nil)
-   ((not (ido-is-ftp-directory dir))
-    t)
-   ((ido-cache-ftp-valid)
-    t)))
+   ((ido-is-unc-host dir)
+    (ido-cache-unc-valid))
+   ((ido-is-ftp-directory dir)
+    (ido-cache-ftp-valid))
+   (t t)))
 
 (defun ido-pp (list &optional sep)
   (let ((print-level nil) (eval-expression-print-level nil)
@@ -1178,25 +1303,24 @@ it doesn't interfere with other minibuffer usage.")
 (defun ido-save-history ()
   "Save ido history and cache information between sessions."
   (interactive)
-  (if (and ido-last-directory-list ido-save-directory-list-file)
-      (save-excursion
-       (save-window-excursion
-         (if (find-buffer-visiting ido-save-directory-list-file)
-             (kill-buffer (find-buffer-visiting ido-save-directory-list-file)))
-         (if (file-exists-p ido-save-directory-list-file)
-             (delete-file ido-save-directory-list-file))
-         (set-buffer (let ((enable-local-variables nil))
-                       (find-file-noselect ido-save-directory-list-file t)))
-         (goto-char (point-min))
-         (delete-region (point-min) (point-max))
-         (ido-pp 'ido-last-directory-list)
-         (ido-pp 'ido-work-directory-list)
-         (ido-pp 'ido-work-file-list)
-         (ido-pp 'ido-dir-file-cache "\n\n ")
-         (insert "\n")
-         (let ((version-control 'never))
+  (when (and ido-last-directory-list ido-save-directory-list-file)
+    (let ((buf (get-buffer-create " *ido session*"))
+         (version-control 'never))
+      (unwind-protect
+         (with-current-buffer buf
+           (erase-buffer)
+           (insert ";;; -*- coding: emacs-mule -*-\n")
+           (setq buffer-file-coding-system 'emacs-mule)
+           (ido-pp 'ido-last-directory-list)
+           (ido-pp 'ido-work-directory-list)
+           (ido-pp 'ido-work-file-list)
+           (ido-pp 'ido-dir-file-cache "\n\n ")
+           (if (listp ido-unc-hosts-cache)
+               (ido-pp 'ido-unc-hosts-cache)
+             (insert "\n;; ----- ido-unc-hosts-cache -----\nt\n"))
+           (insert "\n")
            (write-file ido-save-directory-list-file nil))
-         (kill-buffer (current-buffer))))))
+       (kill-buffer buf)))))
 
 (defun ido-load-history (&optional arg)
   "Load ido history and cache information from previous session.
@@ -1206,18 +1330,19 @@ With prefix argument, reload history unconditionally."
       (let ((file (expand-file-name ido-save-directory-list-file))
            buf)
        (when (file-readable-p file)
-         (save-excursion
-           (save-window-excursion
-             (setq buf (set-buffer (let ((enable-local-variables nil))
-                                     (find-file-noselect file))))
-             (goto-char (point-min))
-             (condition-case nil
-                 (setq ido-last-directory-list (read (current-buffer))
-                       ido-work-directory-list (read (current-buffer))
-                       ido-work-file-list (read (current-buffer))
-                       ido-dir-file-cache (read (current-buffer)))
-               (error nil))))
-         (kill-buffer buf))))
+         (setq buf (get-buffer-create " *ido session*"))
+         (unwind-protect
+             (with-current-buffer buf
+               (erase-buffer)
+               (insert-file-contents file)
+               (condition-case nil
+                   (setq ido-last-directory-list (read (current-buffer))
+                         ido-work-directory-list (read (current-buffer))
+                         ido-work-file-list (read (current-buffer))
+                         ido-dir-file-cache (read (current-buffer))
+                         ido-unc-hosts-cache (read (current-buffer)))
+                 (error nil)))
+           (kill-buffer buf)))))
   (ido-wash-history))
 
 (defun ido-wash-history ()
@@ -1265,15 +1390,21 @@ Removes badly formatted data and ignored directories."
                            (and
                             (stringp dir)
                             (consp time)
-                            (if (integerp (car time))
-                                (and (/= (car time) 0)
-                                     (integerp (car (cdr time)))
-                                     (/= (car (cdr time)) 0)
-                                     (ido-may-cache-directory dir))
-                              (and (eq (car time) 'ftp)
-                                   (numberp (cdr time))
+                            (cond
+                             ((integerp (car time))
+                              (and (/= (car time) 0)
+                                   (integerp (car (cdr time)))
+                                   (/= (car (cdr time)) 0)
+                                   (ido-may-cache-directory dir)))
+                             ((eq (car time) 'ftp)
+                              (and (numberp (cdr time))
                                    (ido-is-ftp-directory dir)
                                    (ido-cache-ftp-valid (cdr time))))
+                             ((eq (car time) 'unc)
+                              (and (numberp (cdr time))
+                                   (ido-is-unc-host dir)
+                                   (ido-cache-unc-valid (cdr time))))
+                             (t nil))
                             (let ((s files) (ok t))
                               (while s
                                 (if (stringp (car s))
@@ -1423,6 +1554,7 @@ With ARG, turn ido speed-up on if arg is positive, off otherwise."
     (define-key map "\C-t" 'ido-toggle-regexp)
     (define-key map "\C-z" 'ido-undo-merge-work-directory)
     (define-key map [(control ?\s)] 'ido-restrict-to-matches)
+    (define-key map [(meta ?\s)] 'ido-take-first-match)
     (define-key map [(control ?@)] 'ido-restrict-to-matches)
     (define-key map [right] 'ido-next-match)
     (define-key map [left] 'ido-prev-match)
@@ -1445,11 +1577,14 @@ With ARG, turn ido speed-up on if arg is positive, off otherwise."
     (define-key map [(meta down)] 'ido-next-work-directory)
     (define-key map [backspace] 'ido-delete-backward-updir)
     (define-key map "\d"        'ido-delete-backward-updir)
-    (define-key map [(meta backspace)] 'ido-delete-backward-word-updir)
+    (define-key map [remap delete-backward-char] 'ido-delete-backward-updir) ; BS
+    (define-key map [remap backward-kill-word] 'ido-delete-backward-word-updir)  ; M-DEL
+
     (define-key map [(control backspace)] 'ido-up-directory)
     (define-key map "\C-l" 'ido-reread-directory)
     (define-key map [(meta ?d)] 'ido-wide-find-dir-or-delete-dir)
     (define-key map [(meta ?b)] 'ido-push-dir)
+    (define-key map [(meta ?v)] 'ido-push-dir-first)
     (define-key map [(meta ?f)] 'ido-wide-find-file-or-pop-dir)
     (define-key map [(meta ?k)] 'ido-forget-work-directory)
     (define-key map [(meta ?m)] 'ido-make-directory)
@@ -1538,6 +1673,7 @@ With ARG, turn ido speed-up on if arg is positive, off otherwise."
   ;; connect on incomplete tramp paths (after entring just method:).
   (let ((ido-enable-tramp-completion nil))
     (and (ido-final-slash dir)
+        (not (ido-is-unc-host dir))
         (file-directory-p dir)
         (not (file-readable-p dir)))))
 
@@ -1548,6 +1684,7 @@ With ARG, turn ido speed-up on if arg is positive, off otherwise."
   (let ((ido-enable-tramp-completion nil))
     (and (numberp ido-max-directory-size)
         (ido-final-slash dir)
+        (not (ido-is-unc-host dir))
         (file-directory-p dir)
         (> (nth 7 (file-attributes dir)) ido-max-directory-size))))
 
@@ -1563,8 +1700,18 @@ With ARG, turn ido speed-up on if arg is positive, off otherwise."
     (unless (and ido-enable-tramp-completion
                 (string-match "\\`/[^/]*@\\'" dir))
       (setq dir (ido-final-slash dir t))))
-  (if (equal dir ido-current-directory)
-      nil
+  (if (get-buffer ido-completion-buffer)
+      (kill-buffer ido-completion-buffer))
+  (cond
+   ((equal dir ido-current-directory)
+    nil)
+   ((ido-is-unc-root dir)
+    (ido-trace "unc" dir)
+    (setq ido-current-directory dir)
+    (setq ido-directory-nonreadable nil)
+    (setq ido-directory-too-big nil)
+    t)
+   (t
     (ido-trace "cd" dir)
     (setq ido-current-directory dir)
     (if (get-buffer ido-completion-buffer)
@@ -1572,7 +1719,7 @@ With ARG, turn ido speed-up on if arg is positive, off otherwise."
     (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))
+    t)))
 
 (defun ido-set-current-home (&optional dir)
   ;; Set ido's current directory to user's home directory
@@ -1654,10 +1801,10 @@ With ARG, turn ido speed-up on if arg is positive, off otherwise."
 ;;       the relevant function is called (find-file, write-file, etc).
 
 (defun ido-read-internal (item prompt history &optional default require-match initial)
-  "Perform the ido-read-buffer and ido-read-file-name functions.
+  "Perform the `ido-read-buffer' and `ido-read-file-name' functions.
 Return the name of a buffer or file selected.
 PROMPT is the prompt to give to the user.
-DEFAULT if given is the default directory to start with.
+DEFAULT if given is the default item to start with.
 If REQUIRE-MATCH is non-nil, an existing file must be selected.
 If INITIAL is non-nil, it specifies the initial input string."
   (let
@@ -1701,13 +1848,19 @@ If INITIAL is non-nil, it specifies the initial input string."
              (cond
               ((eq item 'buffer)
                (if (bufferp default) (buffer-name default) default))
-              ((stringp default) default)
+              ((stringp default)
+               (if (memq item '(file dir))
+                   (file-name-nondirectory default)
+                 default))
               ((eq item 'file)
                (and ido-enable-last-directory-history
                     (let ((d (assoc ido-current-directory ido-last-directory-list)))
                       (and d (cdr d)))))))
        (if (member ido-default-item ido-ignore-item-temp-list)
            (setq ido-default-item nil))
+       (ido-trace "new default" ido-default-item)
+       (if ido-default-item
+           (setq ido-initial-position 0))
        (setq ido-set-default-item nil))
 
       (if ido-process-ignore-lists-inhibit
@@ -1789,8 +1942,14 @@ If INITIAL is non-nil, it specifies the initial input string."
       (if (and ido-matches (eq ido-try-merged-list 'auto))
          (setq ido-try-merged-list t))
       (let
-         ((minibuffer-local-completion-map ido-completion-map)
-          (minibuffer-local-filename-completion-map ido-completion-map)
+         ((minibuffer-local-completion-map
+           (if (memq ido-cur-item '(file dir))
+               minibuffer-local-completion-map
+             ido-completion-map))
+          (minibuffer-local-filename-completion-map
+           (if (memq ido-cur-item '(file dir))
+               ido-completion-map
+             minibuffer-local-filename-completion-map))
           (max-mini-window-height (or ido-max-window-height
                                       (and (boundp 'max-mini-window-height) max-mini-window-height)))
           (ido-completing-read t)
@@ -1911,7 +2070,7 @@ If INITIAL is non-nil, it specifies the initial input string."
             (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"))
+       (error "Must specify valid item"))
 
        (t
        (setq ido-selected
@@ -1935,17 +2094,19 @@ If INITIAL is non-nil, it specifies the initial input string."
              (ido-set-current-directory (file-name-directory (substring ido-current-directory 0 -1))))
          (setq ido-set-default-item t))
 
-        ((and (string-match (if ido-enable-tramp-completion "..[:@]\\'" "..:\\'") ido-selected)
-              (ido-is-root-directory)) ;; Ange-ftp or Tramp
+        ((and (string-match (if ido-enable-tramp-completion ".[:@]\\'" ".:\\'") ido-selected)
+              (ido-is-root-directory) ;; Ange-ftp or Tramp
+              (not (ido-local-file-exists-p ido-selected)))
          (ido-set-current-directory ido-current-directory ido-selected)
          (ido-trace "tramp prefix" ido-selected)
          (if (ido-is-slow-ftp-host)
              (setq ido-exit 'fallback
                    done t)
            (setq ido-set-default-item t)))
+
         ((or (string-match "[/\\][^/\\]" ido-selected)
              (and (memq system-type '(windows-nt ms-dos))
-                  (string-match "\\`.:" ido-selected)))
+                  (string-match "\\`[a-zA-Z]:" ido-selected)))
          (ido-set-current-directory (file-name-directory ido-selected))
          (setq ido-set-default-item t))
 
@@ -1961,8 +2122,10 @@ If INITIAL is non-nil, it specifies the initial input string."
                        (cons (cons ido-current-directory ido-selected) ido-last-directory-list)))))
          (ido-set-current-directory ido-current-directory ido-selected)
          (if ido-input-stack
-             (while ido-input-stack
-               (let ((elt (car ido-input-stack)))
+             ; automatically pop stack elements which match existing files or directories
+             (let (elt)
+               (while (and (setq elt (car ido-input-stack))
+                           (file-exists-p (concat ido-current-directory (cdr elt))))
                  (if (setq ido-input-stack (cdr ido-input-stack))
                      (ido-set-current-directory ido-current-directory (cdr elt))
                    (setq ido-text-init (cdr elt)))
@@ -1974,11 +2137,14 @@ If INITIAL is non-nil, it specifies the initial input string."
     ido-selected))
 
 (defun ido-edit-input ()
-  "Edit absolute file name entered so far with ido; terminate by RET."
+  "Edit absolute file name entered so far with ido; terminate by RET.
+If cursor is not at the end of the user input, move to end of input."
   (interactive)
-  (setq ido-text-init ido-text)
-  (setq ido-exit 'edit)
-  (exit-minibuffer))
+  (if (not (eobp))
+      (end-of-line)
+    (setq ido-text-init (if ido-matches (ido-name (car ido-matches)) ido-text))
+    (setq ido-exit 'edit)
+    (exit-minibuffer)))
 
 ;;; MAIN FUNCTIONS
 (defun ido-buffer-internal (method &optional fallback prompt default initial switch-cmd)
@@ -2006,9 +2172,9 @@ If INITIAL is non-nil, it specifies the initial input string."
 
        ((eq ido-exit 'fallback)
        (let ((read-buffer-function nil))
-         (run-hook-with-args 'ido-before-fallback-functions
-                             (or fallback 'switch-to-buffer))
-         (call-interactively (or fallback 'switch-to-buffer))))
+         (setq this-command (or fallback 'switch-to-buffer))
+         (run-hook-with-args 'ido-before-fallback-functions this-command)
+         (call-interactively this-command)))
 
        ;; Check buf is non-nil.
        ((not buf) nil)
@@ -2016,17 +2182,19 @@ If INITIAL is non-nil, it specifies the initial input string."
 
        ;; View buffer if it exists
        ((get-buffer buf)
+       (add-to-history 'buffer-name-history buf)
        (if (eq method 'insert)
            (progn
              (ido-record-command 'insert-buffer buf)
-             (with-no-warnings
-               ;; we really want to run insert-buffer here
-               (insert-buffer buf)))
+             (push-mark
+              (save-excursion
+                (insert-buffer-substring (get-buffer buf))
+                (point))))
          (ido-visit-buffer buf method t)))
 
        ;; buffer doesn't exist
        ((eq ido-create-new-buffer 'never)
-       (message "no buffer matching `%s'" buf))
+       (message "No buffer matching `%s'" buf))
 
        ((and (eq ido-create-new-buffer 'prompt)
             (not (y-or-n-p (format "No buffer matching `%s', create one? " buf))))
@@ -2034,6 +2202,7 @@ If INITIAL is non-nil, it specifies the initial input string."
 
        ;; create a new buffer
        (t
+       (add-to-history 'buffer-name-history buf)
        (setq buf (get-buffer-create buf))
        (if (fboundp 'set-buffer-major-mode)
            (set-buffer-major-mode buf))
@@ -2087,7 +2256,6 @@ If INITIAL is non-nil, it specifies the initial input string."
   (let ((ido-current-directory (ido-expand-directory default))
        (ido-context-switch-command switch-cmd)
        ido-directory-nonreadable ido-directory-too-big
-       (minibuffer-completing-file-name t)
        filename)
 
     (if (or (not ido-mode) (ido-is-slow-ftp-host))
@@ -2131,9 +2299,12 @@ If INITIAL is non-nil, it specifies the initial input string."
 
       (unless filename
        (setq ido-saved-vc-hb vc-handled-backends)
-       (setq filename (ido-read-internal item
-                                         (or prompt "Find file: ")
-                                         'ido-file-history nil nil initial)))
+       (let ((minibuffer-completing-file-name t))
+         (setq filename (ido-read-internal item
+                                           (or prompt "Find file: ")
+                                           'ido-file-history
+                                           (and (eq method 'alt-file) buffer-file-name)
+                                           nil initial))))
 
       ;; Choose the file name: either the text typed in, or the head
       ;; of the list of matches
@@ -2144,9 +2315,9 @@ If INITIAL is non-nil, it specifies the initial input string."
        ;; we don't want to change directory of current buffer.
        (let ((default-directory ido-current-directory)
              (read-file-name-function nil))
-         (run-hook-with-args 'ido-before-fallback-functions
-                             (or fallback 'find-file))
-         (call-interactively (or fallback 'find-file))))
+         (setq this-command (or fallback 'find-file))
+         (run-hook-with-args 'ido-before-fallback-functions this-command)
+         (call-interactively this-command)))
 
        ((eq ido-exit 'switch-to-buffer)
        (ido-buffer-internal ido-default-buffer-method nil nil nil ido-text))
@@ -2203,7 +2374,9 @@ If INITIAL is non-nil, it specifies the initial input string."
        ((eq method 'write)
        (ido-record-work-file filename)
        (setq default-directory ido-current-directory)
-       (ido-record-command 'write-file (concat ido-current-directory filename))
+       (setq filename (concat ido-current-directory filename))
+       (ido-record-command 'write-file filename)
+       (add-to-history 'file-name-history filename)
        (ido-record-work-directory)
        (write-file filename))
 
@@ -2221,15 +2394,18 @@ If INITIAL is non-nil, it specifies the initial input string."
        (ido-record-command
         (if ido-find-literal 'insert-file-literally 'insert-file)
         filename)
+       (add-to-history 'file-name-history filename)
        (ido-record-work-directory)
-       (if ido-find-literal
-           (insert-file-contents-literally filename)
-         (insert-file-contents filename)))
+       (insert-file-1 filename
+                      (if ido-find-literal
+                          #'insert-file-contents-literally
+                        #'insert-file-contents)))
 
        (filename
        (ido-record-work-file filename)
        (setq filename (concat ido-current-directory filename))
        (ido-record-command 'find-file filename)
+       (add-to-history 'file-name-history filename)
        (ido-record-work-directory)
        (ido-visit-buffer (find-file-noselect filename nil ido-find-literal) method))))))
 
@@ -2242,8 +2418,8 @@ If INITIAL is non-nil, it specifies the initial input string."
 (defun ido-set-common-completion  ()
   ;; Find common completion of `ido-text' in `ido-matches'
   ;; The result is stored in `ido-common-match-string'
-  (let* (val)
-    (setq  ido-common-match-string nil)
+  (let (val)
+    (setq ido-common-match-string nil)
     (if (and ido-matches
             (not ido-enable-regexp) ;; testing
              (stringp ido-text)
@@ -2288,13 +2464,14 @@ If INITIAL is non-nil, it specifies the initial input string."
      ((and (= 1 (length ido-matches))
           (not (and ido-enable-tramp-completion
                     (string-equal ido-current-directory "/")
-                    (string-match "..[@:]\\'" (car ido-matches)))))
+                    (string-match ".[@:]\\'" (ido-name (car ido-matches)))))
+                    (not (ido-local-file-exists-p (ido-name (car ido-matches)))))
       ;; only one choice, so select it.
       (if (not ido-confirm-unique-completion)
          (exit-minibuffer)
        (setq ido-rescan (not ido-enable-prefix))
        (delete-region (minibuffer-prompt-end) (point))
-       (insert (car ido-matches))))
+       (insert (ido-name (car ido-matches)))))
 
      (t ;; else there could be some completions
       (setq res ido-common-match-string)
@@ -2383,14 +2560,18 @@ C-x d ... C-f    fallback to non-ido dired."
 (defun ido-magic-backward-char ()
   "Move backward in user input or perform magic action.
 If no user input is present, or at start of input, perform magic actions:
-C-x C-f C-b  switch to ido-switch-buffer.
-C-x C-d C-b  switch to ido-switch-buffer.
-C-x d C-b    switch to ido-switch-buffer.
-C-x C-b C-b  fallback to non-ido switch-to-buffer."
+C-x C-f C-b  switch to `ido-switch-buffer'.
+C-x C-d C-b  switch to `ido-switch-buffer'.
+C-x d C-b    switch to `ido-switch-buffer'.
+C-x C-b C-b  fallback to non-ido `switch-to-buffer'."
   (interactive)
   (cond
    ((> (point) (minibuffer-prompt-end))
     (forward-char -1))
+   ((eq last-command this-command)
+    (when (and (memq ido-cur-item '(file dir))
+              (not (bobp)))
+      (ido-push-dir))) ; else do nothing
    ((eq ido-cur-item 'buffer)
     (ido-fallback-command))
    (ido-context-switch-command
@@ -2440,12 +2621,16 @@ C-x C-f ... C-d  enter dired on current directory."
 (defun ido-toggle-ignore ()
   "Toggle ignoring files specified with `ido-ignore-files'."
   (interactive)
-  (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))
+  (if (and (not (eobp)) (> (point) (minibuffer-prompt-end)))
+      (goto-char (minibuffer-prompt-end))
+    (if ido-directory-too-big
+       (progn
+         (message "Reading directory...")
+         (setq ido-directory-too-big nil))
+      (setq ido-process-ignore-lists (not ido-process-ignore-lists)))
+    (setq ido-text-init ido-text)
+    (setq ido-exit 'refresh)
+    (exit-minibuffer)))
 
 (defun ido-toggle-vc ()
   "Disable version control for this file."
@@ -2473,9 +2658,11 @@ C-x C-f ... C-d  enter dired on current directory."
 May be useful if cached version is no longer valid, but directory
 timestamp has not changed (e.g. with ftp or on Windows)."
   (interactive)
-  (if (and ido-mode (eq ido-cur-item 'file))
+  (if (and ido-mode (memq ido-cur-item '(file dir)))
       (progn
-       (ido-remove-cached-dir ido-current-directory)
+       (if (ido-is-unc-root)
+           (setq ido-unc-hosts-cache t)
+         (ido-remove-cached-dir ido-current-directory))
        (setq ido-text-init ido-text)
        (setq ido-rotate-temp t)
        (setq ido-exit 'refresh)
@@ -2518,19 +2705,19 @@ If no buffer or file exactly matching the prompt exists, maybe create a new one.
   (exit-minibuffer))
 
 (defun ido-enter-dired ()
-  "Drop into dired from file switching."
+  "Drop into `dired' from file switching."
   (interactive)
   (setq ido-exit 'dired)
   (exit-minibuffer))
 
 (defun ido-enter-insert-buffer ()
-  "Drop into insert buffer from insert file."
+  "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."
+  "Drop into `insert-file' from insert buffer."
   (interactive)
   (setq ido-exit 'insert-file)
   (exit-minibuffer))
@@ -2670,12 +2857,28 @@ If input stack is non-empty, delete current directory component."
       (ido-delete-backward-word-updir 1)
     (ido-wide-find-dir)))
 
+(defun ido-take-first-match ()
+  "Use first matching item as input text."
+  (interactive)
+  (when ido-matches
+    (setq ido-text-init (ido-name (car ido-matches)))
+    (setq ido-exit 'refresh)
+    (exit-minibuffer)))
+
 (defun ido-push-dir ()
   "Move to previous directory in file name, push current input on stack."
   (interactive)
   (setq ido-exit 'push)
   (exit-minibuffer))
 
+(defun ido-push-dir-first ()
+  "Move to previous directory in file name, push first match on stack."
+  (interactive)
+  (if ido-matches
+      (setq ido-text (ido-name (car ido-matches))))
+  (setq ido-exit 'push)
+  (exit-minibuffer))
+
 (defun ido-pop-dir (arg)
   "Pop directory from input stack back to input.
 With \\[universal-argument], pop all element."
@@ -2740,11 +2943,13 @@ With \\[universal-argument], pop all element."
   "Insert file name of current buffer.
 If repeated, insert text from buffer instead."
   (interactive "P")
-  (let* ((bfname (buffer-file-name ido-entry-buffer))
+  (let* ((bfname (or (buffer-file-name ido-entry-buffer)
+                    (buffer-name ido-entry-buffer)))
         (name (and bfname (file-name-nondirectory bfname))))
     (when name
       (setq ido-text-init
            (if (or all
+                   (eq last-command this-command)
                    (not (equal (file-name-directory bfname) ido-current-directory))
                    (not (string-match "\\.[^.]*\\'" name)))
                name
@@ -2759,18 +2964,21 @@ If repeated, insert text from buffer instead."
   (let ((word (save-excursion
                (set-buffer ido-entry-buffer)
                (let ((p (point)) start-line end-line start-name name)
-                 (beginning-of-line)
-                 (setq start-line (point))
-                 (end-of-line)
-                 (setq end-line (point))
-                 (goto-char p)
-                 (if (re-search-backward "[^-_a-zA-Z0-9:./\\~@]" start-line 1)
-                     (forward-char 1))
-                 (setq start-name (point))
-                 (re-search-forward "[-_a-zA-Z0-9:./\\~@]*" end-line 1)
-                 (if (= start-name (point))
-                     nil
-                   (buffer-substring-no-properties start-name (point)))))))
+                 (if (and mark-active (/= p (mark)))
+                     (setq start-name (mark))
+                   (beginning-of-line)
+                   (setq start-line (point))
+                   (end-of-line)
+                   (setq end-line (point))
+                   (goto-char p)
+                   (if (re-search-backward "[^-_a-zA-Z0-9:./\\~@]" start-line 1)
+                       (forward-char 1))
+                   (setq start-name (point))
+                   (re-search-forward "[-_a-zA-Z0-9:./\\~@]*" end-line 1)
+                   (if (= start-name (point))
+                       (setq start-name nil)))
+                 (and start-name
+                      (buffer-substring-no-properties start-name (point)))))))
     (if (cond
         ((not word) nil)
         ((string-match "\\`[~/]" word)
@@ -2926,12 +3134,14 @@ for first matching file."
   (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)))
+      (cond
+       ((= oa ob)
+       lessp)
+       (lessp
+       (> oa ob))
+       (t
+       (< oa ob))))
      (oa
       (not lessp))
      (ob
@@ -2978,7 +3188,12 @@ for first matching file."
   (let ((filenames
         (split-string
          (shell-command-to-string
-          (concat "find " dir " -name \"" (if prefix "" "*") file "*\" -type " (if finddir "d" "f") " -print"))))
+          (concat "find "
+                  (shell-quote-argument dir)
+                  " -name "
+                  (shell-quote-argument
+                   (concat (if prefix "" "*") file "*"))
+                  " -type " (if finddir "d" "f") " -print"))))
        filename d f
        res)
     (while filenames
@@ -3185,36 +3400,52 @@ for first matching file."
 (defun ido-file-name-all-completions (dir)
   ;; Return name of all files in DIR
   ;; Uses and updates ido-dir-file-cache
-  (if (and (numberp ido-max-dir-file-cache) (> ido-max-dir-file-cache 0)
-          (stringp dir) (> (length dir) 0)
-          (ido-may-cache-directory dir))
-      (let* ((cached (assoc dir ido-dir-file-cache))
+  (cond
+   ((ido-is-unc-root dir)
+    (mapcar
+     (lambda (host)
+       (if (string-match "/\\'" host) host (concat host "/")))
+     (ido-unc-hosts t)))
+   ((and (numberp ido-max-dir-file-cache) (> ido-max-dir-file-cache 0)
+        (stringp dir) (> (length dir) 0)
+        (ido-may-cache-directory dir))
+    (let* ((cached (assoc dir ido-dir-file-cache))
             (ctime (nth 1 cached))
             (ftp (ido-is-ftp-directory dir))
-            (attr (if ftp nil (file-attributes dir)))
+            (unc (ido-is-unc-host dir))
+            (attr (if (or ftp unc) nil (file-attributes dir)))
             (mtime (nth 5 attr))
             valid)
        (when cached        ; should we use the cached entry ?
-         (if ftp
-             (setq valid (and (eq (car ctime) 'ftp)
-                              (ido-cache-ftp-valid (cdr ctime))))
+         (cond
+          (ftp
+           (setq valid (and (eq (car ctime) 'ftp)
+                            (ido-cache-ftp-valid (cdr ctime)))))
+          (unc
+           (setq valid (and (eq (car ctime) 'unc)
+                            (ido-cache-unc-valid (cdr ctime)))))
+          (t
            (if attr
                (setq valid (and (= (car ctime) (car mtime))
-                                (= (car (cdr ctime)) (car (cdr mtime)))))))
-         (if (not valid)
-             (setq ido-dir-file-cache (delq cached ido-dir-file-cache)
-                   cached nil)))
+                                (= (car (cdr ctime)) (car (cdr mtime))))))))
+         (unless valid
+           (setq ido-dir-file-cache (delq cached ido-dir-file-cache)
+                 cached nil)))
        (unless cached
-         (if (and ftp (file-readable-p dir))
-             (setq mtime (cons 'ftp (ido-time-stamp))))
+         (cond
+          (unc
+           (setq mtime (cons 'unc (ido-time-stamp))))
+          ((and ftp (file-readable-p dir))
+           (setq mtime (cons 'ftp (ido-time-stamp)))))
          (if mtime
              (setq cached (cons dir (cons mtime (ido-file-name-all-completions-1 dir)))
                    ido-dir-file-cache (cons cached ido-dir-file-cache)))
          (if (> (length ido-dir-file-cache) ido-max-dir-file-cache)
              (setcdr (nthcdr (1- ido-max-dir-file-cache) ido-dir-file-cache) nil)))
        (and cached
-            (cdr (cdr cached))))
-    (ido-file-name-all-completions-1 dir)))
+            (cdr (cdr cached)))))
+   (t
+    (ido-file-name-all-completions-1 dir))))
 
 (defun ido-remove-cached-dir (dir)
   ;; Remove dir from ido-dir-file-cache
@@ -3228,7 +3459,8 @@ for first matching file."
 (defun ido-make-file-list-1 (dir &optional merged)
   ;; Return list of non-ignored files in DIR
   ;; If MERGED is non-nil, each file is cons'ed with DIR
-  (and (or (ido-is-tramp-root dir) (file-directory-p dir))
+  (and (or (ido-is-tramp-root dir) (ido-is-unc-root dir)
+          (file-directory-p dir))
        (delq nil
             (mapcar
              (lambda (name)
@@ -3251,9 +3483,11 @@ for first matching file."
       (let ((default-directory ido-current-directory))
        (ido-to-end ;; move ftp hosts and visited files to end
         (delq nil (mapcar
-                   (lambda (x) (if (or (string-match "..:\\'" x)
+                   (lambda (x) (if (or (and (string-match ".:\\'" x)
+                                            (not (ido-local-file-exists-p x)))
                                        (and (not (ido-final-slash x))
-                                            (get-file-buffer x))) x))
+                                            (let (file-name-handler-alist)
+                                              (get-file-buffer x)))) x))
                    ido-temp-list)))))
     (ido-to-end  ;; move . files to end
      (delq nil (mapcar
@@ -3354,37 +3588,45 @@ for first matching file."
   (let* ((case-fold-search  ido-case-fold)
         (slash (and (not ido-enable-prefix) (ido-final-slash ido-text)))
         (text (if slash (substring ido-text 0 -1) ido-text))
-        (rexq (concat (if ido-enable-regexp text (regexp-quote text)) (if slash ".*/" "")))
+        (rex0 (if ido-enable-regexp text (regexp-quote text)))
+        (rexq (concat rex0 (if slash ".*/" "")))
         (re (if ido-enable-prefix (concat "\\`" rexq) rexq))
-        (full-re (and do-full (not ido-enable-regexp) (not (string-match "\$\\'" re))
-                      (concat "\\`" re "\\'")))
+        (full-re (and do-full (not ido-enable-regexp) (not (string-match "\$\\'" rex0))
+                      (concat "\\`" rex0 (if slash "/" "") "\\'")))
+        (suffix-re (and do-full slash
+                        (not ido-enable-regexp) (not (string-match "\$\\'" rex0))
+                        (concat rex0 "/\\'")))
         (prefix-re (and full-re (not ido-enable-prefix)
                         (concat "\\`" rexq)))
         (non-prefix-dot (or (not ido-enable-dot-prefix)
                             (not ido-process-ignore-lists)
                             ido-enable-prefix
                             (= (length ido-text) 0)))
-
-        full-matches
-        prefix-matches
-        matches)
+        full-matches suffix-matches prefix-matches matches)
     (setq ido-incomplete-regexp nil)
     (condition-case error
         (mapcar
          (lambda (item)
            (let ((name (ido-name item)))
-             (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)))
-                  ((and prefix-re (string-match prefix-re name))
-                   (setq prefix-matches (cons item prefix-matches)))
-                  (t (setq matches (cons item matches))))))
-           t)
+            (if (and (or non-prefix-dot
+                         (if (= (aref ido-text 0) ?.)
+                             (= (aref name 0) ?.)
+                           (/= (aref name 0) ?.)))
+                     (string-match re name))
+                (cond
+                 ((and (eq ido-cur-item 'buffer)
+                       (or (not (stringp ido-default-item))
+                           (not (string= name ido-default-item)))
+                       (string= name (buffer-name ido-entry-buffer)))
+                  (setq matches (cons item matches)))
+                 ((and full-re (string-match full-re name))
+                  (setq full-matches (cons item full-matches)))
+                 ((and suffix-re (string-match suffix-re name))
+                  (setq suffix-matches (cons item suffix-matches)))
+                 ((and prefix-re (string-match prefix-re name))
+                  (setq prefix-matches (cons item prefix-matches)))
+                 (t (setq matches (cons item matches))))))
+          t)
          items)
       (invalid-regexp
        (setq ido-incomplete-regexp t
@@ -3392,10 +3634,15 @@ for first matching file."
              ;; special-case single match, and handle appropriately
              ;; elsewhere.
              matches (cdr error))))
-    (if prefix-matches
-       (setq matches (nconc prefix-matches matches)))
-    (if full-matches
-       (setq matches (nconc full-matches matches)))
+    (when prefix-matches
+      (ido-trace "prefix match" prefix-matches)
+      (setq matches (nconc prefix-matches matches)))
+    (when suffix-matches
+      (ido-trace "suffix match" (list text suffix-re suffix-matches))
+      (setq matches (nconc suffix-matches matches)))
+    (when full-matches
+      (ido-trace "full match" (list text full-re full-matches))
+      (setq matches (nconc full-matches matches)))
     (when (and (null matches)
               ido-enable-flex-matching
               (> (length ido-text) 1)
@@ -3435,7 +3682,7 @@ for first matching file."
                  ((stringp nextstr)
                   (and (>= flen (setq slen (length nextstr)))
                        (string-equal (substring name (- flen slen)) nextstr)))
-                 ((fboundp nextstr) (funcall nextstr name))
+                 ((functionp nextstr) (funcall nextstr name))
                  (t nil))
                 (setq ignorep t
                       ext-list nil
@@ -3445,7 +3692,7 @@ for first matching file."
             (setq nextstr (car re-list))
             (if (cond
                  ((stringp nextstr) (string-match nextstr name))
-                 ((fboundp nextstr) (funcall nextstr name))
+                 ((functionp nextstr) (funcall nextstr name))
                  (t nil))
                 (setq ignorep t
                       re-list nil)
@@ -3524,7 +3771,8 @@ for first matching file."
          (set-buffer temp-buf)
          (setq win (get-buffer-window temp-buf))
          (if (pos-visible-in-window-p (point-max) win)
-             (if (or ido-completion-buffer-all-completions (boundp 'ido-completion-buffer-full))
+             (if (or ido-completion-buffer-all-completions
+                     (boundp 'ido-completion-buffer-full))
                  (set-window-start win (point-min))
                (with-no-warnings
                  (set (make-local-variable 'ido-completion-buffer-full) t))
@@ -3537,6 +3785,14 @@ for first matching file."
        (with-output-to-temp-buffer ido-completion-buffer
          (let ((completion-list (sort
                                  (cond
+                                  (ido-directory-too-big
+                                   (message "Reading directory...")
+                                   (setq ido-directory-too-big nil
+                                         ido-ignored-list nil
+                                         ido-cur-list (ido-all-completions)
+                                         ido-rescan t)
+                                   (ido-set-matches)
+                                   (or ido-matches ido-cur-list))
                                   (ido-use-merged-list
                                    (ido-flatten-merged-list (or ido-matches ido-cur-list)))
                                   ((or full-list ido-completion-buffer-all-completions)
@@ -3552,53 +3808,60 @@ for first matching file."
                  (funcall f completion-list
                           :help-string "ido "
                           :activate-callback
-                          '(lambda (x y z) (message "doesn't work yet, sorry!"))))
+                          '(lambda (x y z) (message "Doesn't work yet, sorry!"))))
              ;; else running Emacs
              ;;(add-hook 'completion-setup-hook 'completion-setup-function)
              (display-completion-list completion-list)))))))
 
 ;;; KILL CURRENT BUFFER
 (defun ido-kill-buffer-at-head ()
-  "Kill the buffer at the head of `ido-matches'."
+  "Kill the buffer at the head of `ido-matches'.
+If cursor is not at the end of the user input, delete to end of input."
   (interactive)
-  (let ((enable-recursive-minibuffers t)
-       (buf (car ido-matches)))
-    (when buf
-      (kill-buffer buf)
-      ;; Check if buffer still exists.
-      (if (get-buffer buf)
-         ;; buffer couldn't be killed.
-         (setq ido-rescan t)
-       ;; else buffer was killed so remove name from list.
-       (setq ido-cur-list (delq buf ido-cur-list))))))
+  (if (not (eobp))
+      (delete-region (point) (line-end-position))
+    (let ((enable-recursive-minibuffers t)
+         (buf (ido-name (car ido-matches))))
+      (when buf
+       (kill-buffer buf)
+       ;; Check if buffer still exists.
+       (if (get-buffer buf)
+           ;; buffer couldn't be killed.
+           (setq ido-rescan t)
+         ;; else buffer was killed so remove name from list.
+         (setq ido-cur-list (delq buf ido-cur-list)))))))
 
 ;;; DELETE CURRENT FILE
 (defun ido-delete-file-at-head ()
-  "Delete the file at the head of `ido-matches'."
+  "Delete the file at the head of `ido-matches'.
+If cursor is not at the end of the user input, delete to end of input."
   (interactive)
-  (let ((enable-recursive-minibuffers t)
-       (file (car ido-matches)))
-    (if file
-       (setq file (concat ido-current-directory file)))
-    (when (and file
-              (file-exists-p file)
-              (not (file-directory-p file))
-              (file-writable-p ido-current-directory)
-              (yes-or-no-p (concat "Delete " file "? ")))
-      (delete-file file)
-      ;; Check if file still exists.
-      (if (file-exists-p file)
-         ;; file could not be deleted
-         (setq ido-rescan t)
-       ;; else file was killed so remove name from list.
-       (setq ido-cur-list (delq (car ido-matches) ido-cur-list))))))
+  (if (not (eobp))
+      (delete-region (point) (line-end-position))
+    (let ((enable-recursive-minibuffers t)
+         (file (ido-name (car ido-matches))))
+      (if file
+         (setq file (concat ido-current-directory file)))
+      (when (and file
+                (file-exists-p file)
+                (not (file-directory-p file))
+                (file-writable-p ido-current-directory)
+                (yes-or-no-p (concat "Delete " file "? ")))
+       (delete-file file)
+       ;; Check if file still exists.
+       (if (file-exists-p file)
+           ;; file could not be deleted
+           (setq ido-rescan t)
+         ;; else file was killed so remove name from list.
+         (setq ido-cur-list (delq (car ido-matches) ido-cur-list)))))))
 
 
 ;;; VISIT CHOSEN BUFFER
 (defun ido-visit-buffer (buffer method &optional record)
-  "Visit file named FILE according to METHOD.
+  "Switch to BUFFER according to METHOD.
 Record command in `command-history' if optional RECORD is non-nil."
-
+  (if (bufferp buffer)
+      (setq buffer (buffer-name buffer)))
   (let (win newframe)
     (cond
      ((eq method 'kill)
@@ -3606,33 +3869,7 @@ Record command in `command-history' if optional RECORD is non-nil."
          (ido-record-command 'kill-buffer buffer))
       (kill-buffer buffer))
 
-     ((eq method 'samewindow)
-      (if record
-         (ido-record-command 'switch-to-buffer buffer))
-      (switch-to-buffer buffer))
-
-     ((memq method '(always-frame maybe-frame))
-      (cond
-       ((and window-system
-            (setq win (ido-window-buffer-p buffer))
-            (or (eq method 'always-frame)
-                (y-or-n-p "Jump to frame? ")))
-       (setq newframe (window-frame win))
-       (if (fboundp 'select-frame-set-input-focus)
-           (select-frame-set-input-focus newframe)
-         (raise-frame newframe)
-         (select-frame newframe)
-         (unless (featurep 'xemacs)
-           (set-mouse-position (selected-frame) (1- (frame-width)) 0)))
-       (select-window win))
-       (t
-       ;;  No buffer in other frames...
-       (if record
-           (ido-record-command 'switch-to-buffer buffer))
-       (switch-to-buffer buffer)
-       )))
-
-     ((eq method 'otherwindow)
+     ((eq method 'other-window)
       (if record
          (ido-record-command 'switch-to-buffer buffer))
       (switch-to-buffer-other-window buffer))
@@ -3640,14 +3877,29 @@ Record command in `command-history' if optional RECORD is non-nil."
      ((eq method 'display)
       (display-buffer buffer))
 
-     ((eq method 'otherframe)
+     ((eq method 'other-frame)
       (switch-to-buffer-other-frame buffer)
-      (unless (featurep 'xemacs)
-       (select-frame-set-input-focus (selected-frame)))
+      (select-frame-set-input-focus (selected-frame)))
+
+     ((and (memq method '(raise-frame maybe-frame))
+          window-system
+          (setq win (ido-buffer-window-other-frame buffer))
+          (or (eq method 'raise-frame)
+              (y-or-n-p "Jump to frame? ")))
+      (setq newframe (window-frame win))
+      (select-frame-set-input-focus newframe)
+      (select-window win))
+
+     ;; (eq method 'selected-window)
+     (t
+      ;;  No buffer in other frames...
+      (if record
+         (ido-record-command 'switch-to-buffer buffer))
+      (switch-to-buffer buffer)
       ))))
 
 
-(defun ido-window-buffer-p  (buffer)
+(defun ido-buffer-window-other-frame  (buffer)
   ;; Return window pointer if BUFFER is visible in another frame.
   ;; If BUFFER is visible in the current frame, return nil.
   (let ((blist (ido-get-buffers-in-frames 'current)))
@@ -3669,7 +3921,7 @@ default is to show it in the same window, unless it is already visible
 in another frame.
 
 As you type in a string, all of the buffers matching the string are
-displayed if substring-matching is used \(default). Look at
+displayed if substring-matching is used \(default).  Look at
 `ido-enable-prefix' and `ido-toggle-prefix'.  When you have found the
 buffer you want, it can then be selected.  As you type, most keys have
 their normal keybindings, except for the following: \\<ido-buffer-completion-map>
@@ -3692,7 +3944,7 @@ in a separate window.
 \\[ido-toggle-prefix] Toggle between substring and prefix matching.
 \\[ido-toggle-case] Toggle case-sensitive searching of buffer names.
 \\[ido-completion-help] Show list of matching buffers in separate window.
-\\[ido-enter-find-file] Drop into ido-find-file.
+\\[ido-enter-find-file] Drop into `ido-find-file'.
 \\[ido-kill-buffer-at-head] Kill buffer at head of buffer list.
 \\[ido-toggle-ignore] Toggle ignoring buffers listed in `ido-ignore-buffers'."
   (interactive)
@@ -3702,15 +3954,15 @@ in a separate window.
 (defun ido-switch-buffer-other-window ()
   "Switch to another buffer and show it in another window.
 The buffer name is selected interactively by typing a substring.
-For details of keybindings, do `\\[describe-function] ido'."
+For details of keybindings, see `ido-switch-buffer'."
   (interactive)
-  (ido-buffer-internal 'otherwindow 'switch-to-buffer-other-window))
+  (ido-buffer-internal 'other-window 'switch-to-buffer-other-window))
 
 ;;;###autoload
 (defun ido-display-buffer ()
   "Display a buffer in another window but don't select it.
 The buffer name is selected interactively by typing a substring.
-For details of keybindings, do `\\[describe-function] ido'."
+For details of keybindings, see `ido-switch-buffer'."
   (interactive)
   (ido-buffer-internal 'display 'display-buffer nil nil nil 'ignore))
 
@@ -3718,7 +3970,7 @@ For details of keybindings, do `\\[describe-function] ido'."
 (defun ido-kill-buffer ()
   "Kill a buffer.
 The buffer name is selected interactively by typing a substring.
-For details of keybindings, do `\\[describe-function] ido'."
+For details of keybindings, see `ido-switch-buffer'."
   (interactive)
   (ido-buffer-internal 'kill 'kill-buffer "Kill buffer: " (buffer-name (current-buffer)) nil 'ignore))
 
@@ -3726,7 +3978,7 @@ For details of keybindings, do `\\[describe-function] ido'."
 (defun ido-insert-buffer ()
   "Insert contents of a buffer in current buffer after point.
 The buffer name is selected interactively by typing a substring.
-For details of keybindings, do `\\[describe-function] ido'."
+For details of keybindings, see `ido-switch-buffer'."
   (interactive)
   (ido-buffer-internal 'insert 'insert-buffer "Insert buffer: " nil nil 'ido-enter-insert-file))
 
@@ -3734,18 +3986,17 @@ For details of keybindings, do `\\[describe-function] ido'."
 (defun ido-switch-buffer-other-frame ()
   "Switch to another buffer and show it in another frame.
 The buffer name is selected interactively by typing a substring.
-For details of keybindings, do `\\[describe-function] ido'."
+For details of keybindings, see `ido-switch-buffer'."
   (interactive)
   (if ido-mode
-      (ido-buffer-internal 'otherframe)
+      (ido-buffer-internal 'other-frame)
     (call-interactively 'switch-to-buffer-other-frame)))
 
 ;;;###autoload
 (defun ido-find-file-in-dir (dir)
   "Switch to another file starting from DIR."
   (interactive "DDir: ")
-  (if (not (equal (substring dir -1) "/"))
-      (setq dir (concat dir "/")))
+  (setq dir (file-name-as-directory dir))
   (ido-file-internal ido-default-file-method nil dir nil nil nil 'ignore))
 
 ;;;###autoload
@@ -3797,15 +4048,15 @@ in a separate window.
 (defun ido-find-file-other-window ()
   "Switch to another file and show it in another window.
 The file name is selected interactively by typing a substring.
-For details of keybindings, do `\\[describe-function] ido-find-file'."
+For details of keybindings, see `ido-find-file'."
   (interactive)
-  (ido-file-internal 'otherwindow 'find-file-other-window))
+  (ido-file-internal 'other-window 'find-file-other-window))
 
 ;;;###autoload
 (defun ido-find-alternate-file ()
   "Switch to another file and show it in another window.
 The file name is selected interactively by typing a substring.
-For details of keybindings, do `\\[describe-function] ido-find-file'."
+For details of keybindings, see `ido-find-file'."
   (interactive)
   (ido-file-internal 'alt-file 'find-alternate-file nil "Find alternate file: "))
 
@@ -3813,7 +4064,7 @@ For details of keybindings, do `\\[describe-function] ido-find-file'."
 (defun ido-find-file-read-only ()
   "Edit file read-only with name obtained via minibuffer.
 The file name is selected interactively by typing a substring.
-For details of keybindings, do `\\[describe-function] ido-find-file'."
+For details of keybindings, see `ido-find-file'."
   (interactive)
   (ido-file-internal 'read-only 'find-file-read-only nil "Find file read-only: "))
 
@@ -3821,7 +4072,7 @@ For details of keybindings, do `\\[describe-function] ido-find-file'."
 (defun ido-find-file-read-only-other-window ()
   "Edit file read-only in other window with name obtained via minibuffer.
 The file name is selected interactively by typing a substring.
-For details of keybindings, do `\\[describe-function] ido-find-file'."
+For details of keybindings, see `ido-find-file'."
   (interactive)
   (ido-file-internal 'read-only 'find-file-read-only-other-window nil "Find file read-only other window: "))
 
@@ -3829,7 +4080,7 @@ For details of keybindings, do `\\[describe-function] ido-find-file'."
 (defun ido-find-file-read-only-other-frame ()
   "Edit file read-only in other frame with name obtained via minibuffer.
 The file name is selected interactively by typing a substring.
-For details of keybindings, do `\\[describe-function] ido-find-file'."
+For details of keybindings, see `ido-find-file'."
   (interactive)
   (ido-file-internal 'read-only 'find-file-read-only-other-frame nil "Find file read-only other frame: "))
 
@@ -3837,7 +4088,7 @@ For details of keybindings, do `\\[describe-function] ido-find-file'."
 (defun ido-display-file ()
   "Display a file in another window but don't select it.
 The file name is selected interactively by typing a substring.
-For details of keybindings, do `\\[describe-function] ido-find-file'."
+For details of keybindings, see `ido-find-file'."
   (interactive)
   (ido-file-internal 'display nil nil nil nil nil 'ignore))
 
@@ -3845,15 +4096,15 @@ For details of keybindings, do `\\[describe-function] ido-find-file'."
 (defun ido-find-file-other-frame ()
   "Switch to another file and show it in another frame.
 The file name is selected interactively by typing a substring.
-For details of keybindings, do `\\[describe-function] ido-find-file'."
+For details of keybindings, see `ido-find-file'."
   (interactive)
-  (ido-file-internal 'otherframe 'find-file-other-frame))
+  (ido-file-internal 'other-frame 'find-file-other-frame))
 
 ;;;###autoload
 (defun ido-write-file ()
   "Write current buffer to a file.
 The file name is selected interactively by typing a substring.
-For details of keybindings, do `\\[describe-function] ido-find-file'."
+For details of keybindings, see `ido-find-file'."
   (interactive)
   (let ((ido-process-ignore-lists t)
        (ido-work-directory-match-only nil)
@@ -3867,24 +4118,24 @@ For details of keybindings, do `\\[describe-function] ido-find-file'."
 (defun ido-insert-file ()
   "Insert contents of file in current buffer.
 The file name is selected interactively by typing a substring.
-For details of keybindings, do `\\[describe-function] ido-find-file'."
+For details of keybindings, see `ido-find-file'."
   (interactive)
   (ido-file-internal 'insert 'insert-file nil "Insert file: " nil nil 'ido-enter-insert-buffer))
 
 ;;;###autoload
 (defun ido-dired ()
-  "Call dired the ido way.
+  "Call `dired' the ido way.
 The directory is selected interactively by typing a substring.
-For details of keybindings, do `\\[describe-function] ido-find-file'."
+For details of keybindings, see `ido-find-file'."
   (interactive)
   (let ((ido-report-no-match nil)
        (ido-auto-merge-work-directories-length -1))
     (ido-file-internal 'dired 'dired nil "Dired: " 'dir)))
 
 (defun ido-list-directory ()
-  "Call list-directory the ido way.
+  "Call `list-directory' the ido way.
 The directory is selected interactively by typing a substring.
-For details of keybindings, do `\\[describe-function] ido-find-file'."
+For details of keybindings, see `ido-find-file'."
   (interactive)
   (let ((ido-report-no-match nil)
        (ido-auto-merge-work-directories-length -1))
@@ -3907,7 +4158,7 @@ For details of keybindings, do `\\[describe-function] ido-find-file'."
   (ido-trace "\n*merge timeout*" buffer)
   (setq ido-auto-merge-timer nil)
   (when (and (buffer-live-p buffer)
-            (= ido-use-mycompletion-depth (minibuffer-depth))
+            (ido-active)
             (boundp 'ido-eoinput) ido-eoinput)
     (let ((contents (buffer-substring-no-properties (minibuffer-prompt-end) ido-eoinput)))
       (ido-trace "request merge")
@@ -3927,18 +4178,19 @@ For details of keybindings, do `\\[describe-function] ido-find-file'."
   ;; 1. It prints a default file name when there is no text yet entered.
   ;; 2. It calls my completion routine rather than the standard completion.
 
-  (when (= ido-use-mycompletion-depth (minibuffer-depth))
+  (when (ido-active)
     (let ((contents (buffer-substring-no-properties (minibuffer-prompt-end) (point-max)))
          (buffer-undo-list t)
          try-single-dir-match
          refresh)
 
-      (ido-trace "\nexhibit" this-command)
-      (ido-trace "dir" ido-current-directory)
-      (ido-trace "contents" contents)
-      (ido-trace "list" ido-cur-list)
-      (ido-trace "matches" ido-matches)
-      (ido-trace "rescan" ido-rescan)
+      (when ido-trace-enable
+       (ido-trace "\nexhibit" this-command)
+       (ido-trace "dir" ido-current-directory)
+       (ido-trace "contents" contents)
+       (ido-trace "list" ido-cur-list)
+       (ido-trace "matches" ido-matches)
+       (ido-trace "rescan" ido-rescan))
 
       (save-excursion
        (goto-char (point-max))
@@ -3957,13 +4209,20 @@ For details of keybindings, do `\\[describe-function] ido-find-file'."
          )
 
         ((= (length contents) 1)
-         (when (and (ido-is-tramp-root) (string-equal contents "/"))
+         (cond
+          ((and (ido-is-tramp-root) (string-equal contents "/"))
            (ido-set-current-directory ido-current-directory contents)
            (setq refresh t))
-         )
+          ((and (ido-unc-hosts) (string-equal contents "/")
+                (let ((ido-enable-tramp-completion nil))
+                  (ido-is-root-directory)))
+           (ido-set-current-directory "//")
+           (setq refresh t))
+         ))
 
-        ((and (string-match (if ido-enable-tramp-completion "..[:@]\\'" "..:\\'") contents)
-              (ido-is-root-directory)) ;; Ange-ftp or tramp
+        ((and (string-match (if ido-enable-tramp-completion ".[:@]\\'" ".:\\'") contents)
+              (ido-is-root-directory) ;; Ange-ftp or tramp
+              (not (ido-local-file-exists-p contents)))
          (ido-set-current-directory ido-current-directory contents)
          (when (ido-is-slow-ftp-host)
            (setq ido-exit 'fallback)
@@ -3981,7 +4240,7 @@ For details of keybindings, do `\\[describe-function] ido-find-file'."
            (setq refresh t))
           ((string-equal contents "./")
            (setq refresh t))
-          ((string-match "\\`~[a-zA-Z0-9]+/\\'" contents)
+          ((string-match "\\`~[-_a-zA-Z0-9]+[$]?/\\'" contents)
            (ido-trace "new home" contents)
            (ido-set-current-home contents)
            (setq refresh t))
@@ -4022,7 +4281,7 @@ For details of keybindings, do `\\[describe-function] ido-find-file'."
            ((= (length contents) 2)
             "/")
            (ido-matches
-            (concat ido-current-directory (car ido-matches)))
+            (concat ido-current-directory (ido-name (car ido-matches))))
            (t
             (concat ido-current-directory (substring contents 0 -1)))))
          (setq ido-text-init (substring contents -1))
@@ -4058,12 +4317,12 @@ For details of keybindings, do `\\[describe-function] ido-find-file'."
                   ido-matches
                   (or (eq ido-enter-matching-directory 'first)
                       (null (cdr ido-matches)))
-                  (ido-final-slash (car ido-matches))
+                  (ido-final-slash (ido-name (car ido-matches)))
                   (or try-single-dir-match
                       (eq ido-enter-matching-directory t)))
          (ido-trace "single match" (car ido-matches))
          (ido-set-current-directory
-          (concat ido-current-directory (car ido-matches)))
+          (concat ido-current-directory (ido-name (car ido-matches))))
          (setq ido-exit 'refresh)
          (exit-minibuffer))
 
@@ -4222,16 +4481,17 @@ For details of keybindings, do `\\[describe-function] ido-find-file'."
 (defun ido-minibuffer-setup ()
   "Minibuffer setup hook for `ido'."
   ;; Copied from `icomplete-minibuffer-setup-hook'.
-  (when (and (boundp 'ido-completing-read)
-            (or (featurep 'xemacs)
-                (= ido-use-mycompletion-depth (minibuffer-depth))))
+  (when (ido-active)
     (add-hook 'pre-command-hook 'ido-tidy nil t)
     (add-hook 'post-command-hook 'ido-exhibit nil t)
     (setq cua-inhibit-cua-keys t)
     (when (featurep 'xemacs)
       (ido-exhibit)
       (goto-char (point-min)))
-    (run-hooks 'ido-minibuffer-setup-hook)))
+    (run-hooks 'ido-minibuffer-setup-hook)
+    (when ido-initial-position
+      (goto-char (+ (minibuffer-prompt-end) ido-initial-position))
+      (setq ido-initial-position nil))))
 
 (defun ido-tidy ()
   "Pre command hook for `ido'."
@@ -4243,8 +4503,7 @@ For details of keybindings, do `\\[describe-function] ido-find-file'."
     (cancel-timer ido-auto-merge-timer)
     (setq ido-auto-merge-timer nil))
 
-  (if (and (boundp 'ido-use-mycompletion-depth)
-          (= ido-use-mycompletion-depth (minibuffer-depth)))
+  (if (ido-active)
       (if (and (boundp 'ido-eoinput)
               ido-eoinput)
 
@@ -4323,6 +4582,8 @@ See `read-file-name' for additional parameters."
             (ido-directory-too-big (and (not ido-directory-nonreadable)
                                         (ido-directory-too-big-p ido-current-directory)))
             (ido-work-directory-index -1)
+            (ido-show-dot-for-dired (and ido-show-dot-for-dired
+                                         (not default-filename)))
             (ido-work-file-index -1)
             (ido-find-literal nil))
        (setq ido-exit nil)