]> code.delx.au - gnu-emacs/blobdiff - lisp/ido.el
(ido-save-history): Set the `coding' local
[gnu-emacs] / lisp / ido.el
index 2d531728b67ee261e36e13824ae97b22ce322991..2a32743907853cd871917daf8c733f665ed88b77 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, 2006 Free Software Foundation, Inc.
+;;   2004, 2005, 2006, 2007 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,
@@ -404,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)
 
@@ -449,7 +449,7 @@ in merged file and directory lists."
 ;(setq ido-ignore-files '("^ " "\\.c$" "\\.h$"))
 
 (defcustom ido-default-file-method  'raise-frame
-    "*How to visit a new file when using `ido-find-file'.
+  "*How to visit a new file when using `ido-find-file'.
 Possible values:
 `selected-window' Show new file in selected window
 `other-window'   Show new file in another window (same frame)
@@ -469,7 +469,7 @@ Possible values:
     :group 'ido)
 
 (defcustom ido-default-buffer-method  'raise-frame
-    "*How to switch to new buffer when using `ido-switch-buffer'.
+  "*How to switch to new buffer when using `ido-switch-buffer'.
 See `ido-default-file-method' for details."
     :type '(choice (const :tag "Show in selected window" selected-window)
                   (const :tag "Show in other window" other-window)
@@ -503,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)
@@ -714,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
@@ -777,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,
@@ -795,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))
@@ -809,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))
@@ -821,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
@@ -864,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)
@@ -898,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:
 
@@ -1034,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
@@ -1116,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)
 
@@ -1142,6 +1151,11 @@ 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
@@ -1295,6 +1309,8 @@ it doesn't interfere with other minibuffer usage.")
       (unwind-protect
          (with-current-buffer buf
            (erase-buffer)
+           (insert ";;; -*- coding: utf-8 -*-\n")
+           (setq buffer-file-coding-system 'utf-8)
            (ido-pp 'ido-last-directory-list)
            (ido-pp 'ido-work-directory-list)
            (ido-pp 'ido-work-file-list)
@@ -1561,7 +1577,9 @@ 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)
@@ -1841,6 +1859,8 @@ If INITIAL is non-nil, it specifies the initial input string."
        (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
@@ -1922,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)
@@ -2044,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
@@ -2068,8 +2094,9 @@ 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)
@@ -2079,7 +2106,7 @@ If INITIAL is non-nil, it specifies the initial input string."
 
         ((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))
 
@@ -2110,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 (if ido-matches (car ido-matches) 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)
@@ -2142,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)
@@ -2152,6 +2182,7 @@ 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)
@@ -2163,7 +2194,7 @@ If INITIAL is non-nil, it specifies the initial input string."
 
        ;; 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))))
@@ -2171,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))
@@ -2224,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))
@@ -2251,9 +2282,10 @@ If INITIAL is non-nil, it specifies the initial input string."
                filename t))
 
         ((and ido-use-filename-at-point
-              (setq fn (if (eq ido-use-filename-at-point 'guess)
-                           (with-no-warnings (ffap-guesser))
-                         (ffap-string-at-point)))
+              (setq fn (with-no-warnings
+                         (if (eq ido-use-filename-at-point 'guess)
+                             (ffap-guesser)
+                           (ffap-string-at-point))))
               (not (string-match "^http:/" fn))
               (setq d (file-name-directory fn))
               (file-directory-p d))
@@ -2268,9 +2300,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
@@ -2281,9 +2316,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))
@@ -2340,9 +2375,11 @@ 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 (concat ido-current-directory filename)))
+       (write-file filename))
 
        ((eq method 'read-only)
        (ido-record-work-file filename)
@@ -2358,6 +2395,7 @@ 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)
        (insert-file-1 filename
                       (if ido-find-literal
@@ -2368,6 +2406,7 @@ If INITIAL is non-nil, it specifies the initial input string."
        (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))))))
 
@@ -2380,8 +2419,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)
@@ -2426,13 +2465,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)
@@ -2521,14 +2561,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
@@ -2578,12 +2622,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."
@@ -2611,7 +2659,7 @@ 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
        (if (ido-is-unc-root)
            (setq ido-unc-hosts-cache t)
@@ -2658,19 +2706,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))
@@ -2814,7 +2862,7 @@ If input stack is non-empty, delete current directory component."
   "Use first matching item as input text."
   (interactive)
   (when ido-matches
-    (setq ido-text-init (car ido-matches))
+    (setq ido-text-init (ido-name (car ido-matches)))
     (setq ido-exit 'refresh)
     (exit-minibuffer)))
 
@@ -2828,7 +2876,7 @@ If input stack is non-empty, delete current directory component."
   "Move to previous directory in file name, push first match on stack."
   (interactive)
   (if ido-matches
-      (setq ido-text (car ido-matches)))
+      (setq ido-text (ido-name (car ido-matches))))
   (setq ido-exit 'push)
   (exit-minibuffer))
 
@@ -2917,18 +2965,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)
@@ -3084,12 +3135,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
@@ -3136,7 +3189,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
@@ -3299,7 +3357,7 @@ for first matching file."
 
 (defun ido-to-end (items)
   ;; Move the elements from ITEMS to the end of `ido-temp-list'
-  (mapcar
+  (mapc
    (lambda (elem)
      (setq ido-temp-list (delq elem ido-temp-list)))
    items)
@@ -3307,6 +3365,8 @@ for first matching file."
       (nconc ido-temp-list items)
     (setq ido-temp-list items)))
 
+(declare-function tramp-tramp-file-p "net/tramp" (name))
+
 (defun ido-file-name-all-completions-1 (dir)
   (cond
    ((ido-nonreadable-directory-p dir) '())
@@ -3314,24 +3374,25 @@ for first matching file."
    ;; Caller must have done that if necessary.
 
    ((and ido-enable-tramp-completion
-        (or (fboundp 'tramp-completion-mode)
+        (or (fboundp 'tramp-completion-mode-p)
             (require 'tramp nil t))
         (string-match "\\`/[^/]+[:@]\\'" dir))
     ;; Strip method:user@host: part of tramp completions.
     ;; Tramp completions do not include leading slash.
-    (let ((len (1- (length dir)))
-         (compl
-          (or (file-name-all-completions "" dir)
-              ;; work around bug in ange-ftp.
-              ;; /ftp:user@host: => nil
-              ;; /ftp:user@host:./ => ok
-              (and
-               (not (string= "/ftp:" dir))
-               (tramp-tramp-file-p dir)
-               (fboundp 'tramp-ftp-file-name-p)
-               (funcall 'tramp-ftp-file-name-p dir)
-               (string-match ":\\'" dir)
-               (file-name-all-completions "" (concat dir "./"))))))
+    (let* ((len (1- (length dir)))
+          (tramp-completion-mode t)
+          (compl
+           (or (file-name-all-completions "" dir)
+               ;; work around bug in ange-ftp.
+               ;; /ftp:user@host: => nil
+               ;; /ftp:user@host:./ => ok
+               (and
+                (not (string= "/ftp:" dir))
+                (tramp-tramp-file-p dir)
+                (fboundp 'tramp-ftp-file-name-p)
+                (funcall 'tramp-ftp-file-name-p dir)
+                (string-match ":\\'" dir)
+                (file-name-all-completions "" (concat dir "./"))))))
       (if (and compl
               (> (length (car compl)) len)
               (string= (substring (car compl) 0 len) (substring dir 1)))
@@ -3426,9 +3487,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
@@ -3546,7 +3609,7 @@ for first matching file."
         full-matches suffix-matches prefix-matches matches)
     (setq ido-incomplete-regexp nil)
     (condition-case error
-        (mapcar
+        (mapc
          (lambda (item)
            (let ((name (ido-name item)))
             (if (and (or non-prefix-dot
@@ -3555,6 +3618,11 @@ for first matching file."
                            (/= (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))
@@ -3586,7 +3654,7 @@ for first matching file."
       (setq re (mapconcat #'regexp-quote (split-string ido-text "") ".*"))
       (if ido-enable-prefix
          (setq re (concat "\\`" re)))
-      (mapcar
+      (mapc
        (lambda (item)
         (let ((name (ido-name item)))
           (if (string-match re name)
@@ -3618,7 +3686,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
@@ -3628,7 +3696,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)
@@ -3707,7 +3775,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))
@@ -3720,6 +3789,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)
@@ -3735,53 +3812,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)
   "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)
@@ -3874,7 +3958,7 @@ 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 'other-window 'switch-to-buffer-other-window))
 
@@ -3882,7 +3966,7 @@ For details of keybindings, do `\\[describe-function] ido'."
 (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))
 
@@ -3890,7 +3974,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))
 
@@ -3898,7 +3982,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))
 
@@ -3906,7 +3990,7 @@ 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 'other-frame)
@@ -3916,8 +4000,7 @@ For details of keybindings, do `\\[describe-function] ido'."
 (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
@@ -3969,7 +4052,7 @@ 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 'other-window 'find-file-other-window))
 
@@ -3977,7 +4060,7 @@ For details of keybindings, do `\\[describe-function] ido-find-file'."
 (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: "))
 
@@ -3985,7 +4068,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: "))
 
@@ -3993,7 +4076,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: "))
 
@@ -4001,7 +4084,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: "))
 
@@ -4009,7 +4092,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))
 
@@ -4017,7 +4100,7 @@ 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 'other-frame 'find-file-other-frame))
 
@@ -4025,7 +4108,7 @@ For details of keybindings, do `\\[describe-function] ido-find-file'."
 (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)
@@ -4039,24 +4122,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))
@@ -4079,7 +4162,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")
@@ -4099,7 +4182,7 @@ 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
@@ -4141,8 +4224,9 @@ For details of keybindings, do `\\[describe-function] ido-find-file'."
            (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)
@@ -4160,7 +4244,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))
@@ -4201,7 +4285,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))
@@ -4237,12 +4321,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))
 
@@ -4401,16 +4485,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'."
@@ -4422,8 +4507,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)