changeset 49180:b76c3354f4e7

(ido-enable-tramp-completion): New defcustom. (ido-enter-single-matching-directory): Change default to 'slash. (ido-is-tramp-root): New defun. (ido-is-root-directory, ido-is-ftp-directory, ido-is-slow-ftp-host) (ido-may-cache-directory, ido-final-slash, ido-read-internal) (ido-complete, ido-make-file-list1, ido-make-dir-list1): Handle tramp completion. (ido-file-name-all-completions1): New defun for tramp completion. (ido-file-name-all-completions): Use it. (ido-set-matches1): Relax matching of text with trailing slash. (ido-exhibit): Handle tramp completion. Simplified code using nested cond forms using new `refresh' var. Fixed handling of /~user/ paths.
author Kim F. Storm <storm@cua.dk>
date Sun, 12 Jan 2003 22:27:17 +0000
parents 5dbe42c838b7
children 94d20f0ab516
files lisp/ido.el
diffstat 1 files changed, 283 insertions(+), 204 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/ido.el	Sun Jan 12 22:23:22 2003 +0000
+++ b/lisp/ido.el	Sun Jan 12 22:27:17 2003 +0000
@@ -552,6 +552,13 @@
   :type '(repeat regexp)
   :group 'ido)
 
+
+(defcustom ido-enable-tramp-completion t
+  "*Non-nil means that ido shall perform tramp method and server name completion.
+A tramp file name uses the following syntax: /method:user@host:path."
+  :type 'boolean
+  :group 'ido)
+
 (defcustom ido-record-ftp-work-directories t
   "*Non-nil means that ftp paths are recorded in work directory list."
   :type 'boolean
@@ -636,7 +643,7 @@
   :type 'boolean
   :group 'ido)
 
-(defcustom ido-enter-single-matching-directory nil
+(defcustom ido-enter-single-matching-directory 'slash
   "*Automatically enter sub-directory if it is the only matching item, if non-nil.
 If value is 'slash, only enter if typing final slash, else do it always."
   :type '(choice (const :tag "Never" nil) 
@@ -973,27 +980,47 @@
 (defun ido-toggle-trace (arg)
   (interactive "P")
   (setq ido-trace-enable (or arg (not ido-trace-enable)))
+  (if ido-trace-enable
+      (message "IDO trace on"))
   (let ((b (get-buffer " *IDO Trace*")))
     (if b
 	(if ido-trace-enable
 	    (kill-buffer b)
-	  (pop-to-buffer b t t)))))
+	  (pop-to-buffer b t t)
+	  (setq truncate-lines t)))))
+
+(defun ido-is-tramp-root (&optional dir)
+  (setq dir (or dir ido-current-directory))
+  (and ido-enable-tramp-completion
+       (string-match "\\`/[^/][^/]+:\\([^/:@]+@\\)?\\'" dir)))
 
 (defun ido-is-root-directory (&optional dir)
   (setq dir (or dir ido-current-directory))
-  (if (memq system-type '(windows-nt ms-dos))
-      (string-match "\\`[a-zA-Z]:[/\\]\\'" dir)
-    (string-equal "/" dir)))
+  (or
+   (string-equal "/" dir)
+   (and (memq system-type '(windows-nt ms-dos))
+	(string-match "\\`[a-zA-Z]:[/\\]\\'" dir))
+   (if ido-enable-tramp-completion
+       (ido-is-tramp-root dir)
+     (string-match "\\`/[^:/][^:/]+:\\'" dir))))
 
 (defun ido-is-ftp-directory (&optional dir)
-  (string-match "\\`/[^/:][^/:]+:/" (or dir ido-current-directory)))
+  (string-match 
+   (if ido-enable-tramp-completion
+       "\\`/[^/:][^/:]+:"  ;; like tramp-file-name-regexp-unified, but doesn't match single drive letters
+     "\\`/[^/:][^/:]+:/")
+   (or dir ido-current-directory)))
 
 (defun ido-is-slow-ftp-host (&optional dir)
   (and (or ido-slow-ftp-hosts ido-slow-ftp-host-regexps)
        (setq dir (or dir ido-current-directory))
        ;; (featurep 'ange-ftp)
        ;; (ange-ftp-ftp-name dir)
-       (string-match "\\`/\\([^/:]*@\\)?\\([^@/:][^@/:]+\\):/" dir)
+       (string-match 
+	(if ido-enable-tramp-completion
+	    "\\`/\\([^/]+[@:]\\)*\\([^@/:][^@/:]+\\):"
+	  "\\`/\\([^/:]*@\\)?\\([^@/:][^@/:]+\\):/")
+	dir)
        (let ((host (substring dir (match-beginning 2) (match-end 2))))
 	 (or (member host ido-slow-ftp-hosts)
 	     (let ((re ido-slow-ftp-host-regexps))
@@ -1014,11 +1041,15 @@
 
 (defun ido-may-cache-directory (&optional dir)
   (setq dir (or dir ido-current-directory))
-  (if (and (memq system-type '(windows-nt ms-dos))
-	   (string-match "\\`[a-zA-Z]:[/\\]\\'" dir))
-      nil
-    (or (not (ido-is-ftp-directory dir))
-	(ido-cache-ftp-valid))))
+  (cond
+   ((and (ido-is-root-directory dir)
+	 (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)))
 
 (defun ido-pp (list &optional sep)
   (let ((print-level nil) (eval-expression-print-level nil)
@@ -1328,6 +1359,7 @@
   (setq dir (ido-name dir))
   (cond
    ((string-match "/\\'" dir) dir)
+   ((ido-is-tramp-root dir) dir)
    (fix-it (concat dir "/"))
    (t nil)))
 
@@ -1459,7 +1491,7 @@
     (ido-define-mode-map)
     (setq ido-text-init initial)
     (while (not done)
-      (ido-trace "\n_LOOP_")
+      (ido-trace "\n_LOOP_" ido-text-init)
       (setq ido-exit nil)
       (setq ido-rescan t)
       (setq ido-rotate nil)
@@ -1612,7 +1644,6 @@
 		    (setq ido-text-init f
 			  path nil))))))
 	 (t
-	  (setq ido-text-init nil)
 	  (setq ido-text-init (read-string (concat prompt "[EDIT] ") ido-final-text))))
 	nil)
 
@@ -1625,9 +1656,14 @@
        ((eq ido-exit 'updir)
 	;; cannot go up if already at the root-dir (Unix) or at the
 	;; root-dir of a certain drive (Windows or MS-DOS).
-        (or (ido-is-root-directory)
-	    (ido-set-current-directory (file-name-directory (substring ido-current-directory 0 -1))))
-	(setq ido-set-default-item t))
+        (if (ido-is-tramp-root)
+	    (when (string-match "\\`\\(/\\([^/]+[:@]\\)*\\)\\([^/]+\\)[:@]\\'" ido-current-directory)
+	      (setq ido-text-init (match-string 3 ido-current-directory))
+	      (ido-set-current-directory (match-string 1 ido-current-directory))
+	      (setq ido-set-default-item t))
+	  (unless (ido-is-root-directory)
+	    (ido-set-current-directory (file-name-directory (substring ido-current-directory 0 -1)))
+	    (setq ido-set-default-item t))))
 
        ;; Handling the require-match must be done in a better way.
        ((and require-match (not (ido-existing-item-p)))
@@ -1654,14 +1690,15 @@
 	  (or (ido-is-root-directory)
 	      (ido-set-current-directory (file-name-directory (substring ido-current-directory 0 -1))))
 	  (setq ido-set-default-item t))
-	 ((and (string-equal ido-current-directory "/")
-	       (string-match "..:\\'" ido-selected)) ;; Ange-ftp 
-	  (ido-set-current-directory "/" ido-selected)
+
+	 ((and (string-match (if ido-enable-tramp-completion "..[:@]\\'" "..:\\'") ido-selected)
+	       (ido-is-root-directory)) ;; Ange-ftp or Tramp
+	  (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)))
@@ -1936,7 +1973,10 @@
       (when ido-completion-buffer
 	(call-interactively (setq this-command ido-cannot-complete-command))))
 	  
-     ((= 1 (length ido-matches))
+     ((and (= 1 (length ido-matches))
+	   (not (and ido-enable-tramp-completion
+		     (string-equal ido-current-directory "/")
+		     (string-match "..[@:]\\'" (car ido-matches)))))
       ;; only one choice, so select it.
       (exit-minibuffer))
 	  
@@ -2582,6 +2622,32 @@
       (nconc ido-temp-list items)
     (setq ido-temp-list items)))
 
+(defun ido-file-name-all-completions1 (dir)
+  (if (and ido-enable-tramp-completion
+	   (string-match "\\`/\\([^/:]+:\\([^/:@]+@\\)?\\)\\'" dir))
+
+      ;; Trick tramp's file-name-all-completions handler to DTRT, as it
+      ;; has some pretty obscure requirements.  This seems to work...
+      ;; /ftp:		=> (f-n-a-c "/ftp:" "")
+      ;; /ftp:kfs:	=> (f-n-a-c "" "/ftp:kfs:")
+      ;; /ftp:kfs@      => (f-n-a-c "ftp:kfs@" "/")
+      ;; /ftp:kfs@kfs:  => (f-n-a-c "" "/ftp:kfs@kfs:")
+      ;; Currently no attempt is made to handle multi: stuff.
+
+      (let* ((prefix (match-string 1 dir))
+	     (user-flag (match-beginning 2))
+	     (len (and prefix (length prefix)))
+	     compl)
+	(if user-flag
+	    (setq dir (substring dir 1)))
+	(require 'tramp nil t)
+	(ido-trace "tramp complete" dir)
+	(setq compl (file-name-all-completions dir (if user-flag "/" "")))
+	(if (> len 0)
+	    (mapcar (lambda (c) (substring c len)) compl)
+	  compl))
+    (file-name-all-completions "" dir)))
+
 (defun ido-file-name-all-completions (dir)
   ;; Return name of all files in DIR
   ;; Uses and updates ido-dir-file-cache
@@ -2608,13 +2674,13 @@
 	  (if (and ftp (file-readable-p dir))
 	      (setq mtime (cons 'ftp (ido-time-stamp))))
 	  (if mtime
-	      (setq cached (cons dir (cons mtime (file-name-all-completions "" dir)))
+	      (setq cached (cons dir (cons mtime (ido-file-name-all-completions1 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))))
-    (file-name-all-completions "" dir)))
+    (ido-file-name-all-completions1 dir)))
 
 (defun ido-remove-cached-dir (dir)
   ;; Remove dir from ido-dir-file-cache
@@ -2628,7 +2694,7 @@
 (defun ido-make-file-list1 (dir &optional merged)
   ;; Return list of non-ignored files in DIR
   ;; If MERGED is non-nil, each file is cons'ed with DIR
-  (and (file-directory-p dir)
+  (and (or (ido-is-tramp-root dir) (file-directory-p dir))
        (delq nil 
 	     (mapcar
 	      (lambda (name)
@@ -2676,7 +2742,7 @@
 (defun ido-make-dir-list1 (dir &optional merged)
   ;; Return list of non-ignored subdirs in DIR
   ;; If MERGED is non-nil, each subdir is cons'ed with DIR
-  (and (file-directory-p dir)
+  (and (or (ido-is-tramp-root dir) (file-directory-p dir))
        (delq nil 
 	     (mapcar
 	      (lambda (name)
@@ -2750,7 +2816,9 @@
 (defun ido-set-matches1 (items &optional do-full)
   ;; Return list of matches in items
   (let* ((case-fold-search  ido-case-fold)
-	 (rexq (if ido-enable-regexp ido-text (regexp-quote ido-text)))
+	 (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 ".*/" "")))
 	 (re (if ido-enable-prefix (concat "\\`" rexq) rexq))
 	 (full-re (and do-full (not ido-enable-regexp) (not (string-match "\$\\'" re))
 		       (concat "\\`" re "\\'")))
@@ -3304,188 +3372,199 @@
   ;; 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.
 
-  (if (= ido-use-mycompletion-depth (minibuffer-depth))
-      (let ((contents (buffer-substring-no-properties (minibuffer-prompt-end) (point-max)))
-	    (buffer-undo-list t)
-	    try-single-dir-match)
-
-	(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))
-	  ;; Register the end of input, so we know where the extra stuff (match-status info) begins:
-	  (if (not (boundp 'ido-eoinput))
-	      ;; In case it got wiped out by major mode business:
-	      (make-local-variable 'ido-eoinput))
-	  (setq ido-eoinput (point))
-
-	  ;; Handle explicit directory changes
-	  (and
-	   (memq ido-cur-item '(file dir))
-	   (> (length contents) 1)
+  (when (= ido-use-mycompletion-depth (minibuffer-depth))
+    (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)
+
+      (save-excursion
+	(goto-char (point-max))
+	;; Register the end of input, so we know where the extra stuff (match-status info) begins:
+	(unless (boundp 'ido-eoinput)
+	  ;; In case it got wiped out by major mode business:
+	  (make-local-variable 'ido-eoinput))
+	(setq ido-eoinput (point))
+
+	;; Handle explicit directory changes
+	(cond
+	 ((eq ido-cur-item 'buffer)
+	  )
+
+	 ((= (length contents) 0)
+	  )
+
+	 ((= (length contents) 1)
+	  (when (and (ido-is-tramp-root) (string-equal contents "/"))
+	    (ido-set-current-directory ido-current-directory contents)
+	    (setq refresh t))
+	  )
+
+	 ((and (string-match (if ido-enable-tramp-completion "..[:@]\\'" "..:\\'") contents)
+	       (ido-is-root-directory)) ;; Ange-ftp or tramp
+	  (ido-set-current-directory ido-current-directory contents)
+	  (when (ido-is-slow-ftp-host)
+	    (setq ido-exit 'fallback)
+	    (exit-minibuffer))
+	  (setq refresh t))
+
+	 ((ido-final-slash contents)  ;; xxx/
+	  (ido-trace "final slash" contents)
+	  (cond 
+	   ((string-equal contents "~/")
+	    (ido-set-current-home)
+	    (setq refresh t))
+	   ((string-equal contents "../")
+	    (ido-up-directory t)
+	    (setq refresh t))
+	   ((string-equal contents "./")
+	    (setq refresh t))
+	   ((string-match "\\`~[a-zA-Z0-9]+/\\'" contents)
+	    (ido-trace "new home" contents)
+	    (ido-set-current-home contents)
+	    (setq refresh t))
+	   ((string-match "[$][A-Za-z0-9_]+/\\'" contents)
+	    (let ((exp (condition-case ()
+			   (expand-file-name
+			    (substitute-in-file-name (substring contents 0 -1))
+			    ido-current-directory)
+			 (error nil))))
+	      (ido-trace contents exp)
+	      (when (and exp (file-directory-p exp))
+		(ido-set-current-directory (file-name-directory exp))
+		(setq ido-text-init (file-name-nondirectory exp))
+		(setq refresh t))))
+	   ((and (memq system-type '(windows-nt ms-dos))
+		 (string-equal (substring contents 1) ":/"))
+	    (ido-set-current-directory (file-name-directory contents))
+	    (setq refresh t))
+	   ((string-equal (substring contents -2 -1) "/")
+	    (ido-set-current-directory 
+	     (if (memq system-type '(windows-nt ms-dos))
+		 (expand-file-name "/" ido-current-directory)
+	       "/"))
+	    (setq refresh t))
+	   (t
+	    (ido-trace "try single dir")
+	    (setq try-single-dir-match t))))
+
+	 ((and (string-equal (substring contents -2 -1) "/")
+	       (not (string-match "[$]" contents)))
+	  (ido-set-current-directory
 	   (cond
-	    ((ido-final-slash contents)  ;; xxx/
-	     (ido-trace "final slash" contents)
-	     (cond 
-	      ((string-equal contents "~/")
-	       (ido-set-current-home)
-	       t)
-	      ((string-equal contents "../")
-	       (ido-up-directory t)
-	       t)
-	      ((string-equal contents "./")
-	       t)
-	      ((string-match contents "\\`~[a-zA-Z0-9]/\\'")
-	       (ido-set-current-home contents)
-	       t)
-	      ((string-match "[$][A-Za-z0-9_]+/\\'" contents)
-	       (let ((exp (condition-case ()
-			      (expand-file-name
-			       (substitute-in-file-name (substring contents 0 -1))
-			       ido-current-directory)
-			    (error nil))))
-		 (ido-trace contents exp)
-		 (if (and exp (file-directory-p exp))
-		     (progn
-		       (ido-set-current-directory (file-name-directory exp))
-		       (setq ido-text-init (file-name-nondirectory exp))
-		       t)
-		   nil)))
-	      ((and (memq system-type '(windows-nt ms-dos))
-		    (string-equal (substring contents 1) ":/"))
-	       (ido-set-current-directory (file-name-directory contents))
-	       t)
-	      ((string-equal (substring contents -2 -1) "/")
-	       (ido-set-current-directory 
-		(if (memq system-type '(windows-nt ms-dos))
-		    (expand-file-name "/" ido-current-directory)
-		  "/"))
-	       t)
-	      (t 
-	       (setq try-single-dir-match t)
-	       nil)))
-
-	    ((and (string-equal ido-current-directory "/")
-		  (string-match "..:\\'" contents)) ;; Ange-ftp 
-	     (ido-set-current-directory "/" contents)
-	     (when (ido-is-slow-ftp-host)
-	       (setq ido-exit 'fallback)
-	       (exit-minibuffer))
-	     t)
-
-	    ((and (string-equal (substring contents -2 -1) "/")
-		  (not (string-match "[$]" contents)))
-	     (ido-set-current-directory
-	      (cond
-	       ((= (length contents) 2)
-		"/")
-	       (ido-matches
-		(concat ido-current-directory (car ido-matches)))
-	       (t
-		(concat ido-current-directory (substring contents 0 -1)))))
-	     (setq ido-text-init (substring contents -1))
-	     t)
-
-	    ((and (not ido-use-merged-list)
-		  (not (ido-final-slash contents))
-		  (eq ido-try-merged-list t)
-		  (numberp ido-auto-merge-work-directories-length)
-		  (> ido-auto-merge-work-directories-length 0)
-		  (= (length contents) ido-auto-merge-work-directories-length)
-		  (not (and ido-auto-merge-inhibit-characters-regexp
-			    (string-match ido-auto-merge-inhibit-characters-regexp contents)))
-		  (not (input-pending-p)))
-	     (setq ido-use-merged-list 'auto
-		   ido-text-init contents
-		   ido-rotate-temp t)
-	     t))
-	   (progn
-	     (ido-trace "refresh on /" ido-text-init)
-	     (setq ido-exit 'refresh)
-	     (exit-minibuffer)))
-
-	  ;; Update the list of matches
-	  (setq ido-text contents)
-	  (ido-set-matches)
-	  (ido-trace "new    " ido-matches)
-
-	  (when (and ido-enter-single-matching-directory
-		     ido-matches
-		     (null (cdr ido-matches))
-		     (ido-final-slash (car ido-matches))
-		     (or try-single-dir-match
-			 (eq ido-enter-single-matching-directory t)))
-	    (ido-trace "single match" (car ido-matches))
-	    (ido-set-current-directory 
+	    ((= (length contents) 2)
+	     "/")
+	    (ido-matches
 	     (concat ido-current-directory (car ido-matches)))
-	    (setq ido-exit 'refresh)
-	    (exit-minibuffer))
-
-	  (when (and (not ido-matches)
-		   ; ido-rescan
+	    (t
+	     (concat ido-current-directory (substring contents 0 -1)))))
+	  (setq ido-text-init (substring contents -1))
+	  (setq refresh t))
+
+	 ((and (not ido-use-merged-list)
+	       (not (ido-final-slash contents))
+	       (eq ido-try-merged-list t)
+	       (numberp ido-auto-merge-work-directories-length)
+	       (> ido-auto-merge-work-directories-length 0)
+	       (= (length contents) ido-auto-merge-work-directories-length)
+	       (not (and ido-auto-merge-inhibit-characters-regexp
+			 (string-match ido-auto-merge-inhibit-characters-regexp contents)))
+	       (not (input-pending-p)))
+	  (setq ido-use-merged-list 'auto
+		ido-text-init contents
+		ido-rotate-temp t)
+	  (setq refresh t))
+
+	 (t nil))
+
+	(when refresh
+	  (ido-trace "refresh on /" ido-text-init)
+	  (setq ido-exit 'refresh)
+	  (exit-minibuffer))
+
+	;; Update the list of matches
+	(setq ido-text contents)
+	(ido-set-matches)
+	(ido-trace "new    " ido-matches)
+
+	(when (and ido-enter-single-matching-directory
+		   ido-matches
+		   (null (cdr ido-matches))
+		   (ido-final-slash (car ido-matches))
+		   (or try-single-dir-match
+		       (eq ido-enter-single-matching-directory t)))
+	  (ido-trace "single match" (car ido-matches))
+	  (ido-set-current-directory 
+	   (concat ido-current-directory (car ido-matches)))
+	  (setq ido-exit 'refresh)
+	  (exit-minibuffer))
+
+	(when (and (not ido-matches)
+		   ;; ido-rescan ?
 		   ido-process-ignore-lists
 		   ido-ignored-list)
-	      (let ((ido-process-ignore-lists nil)
-		    (ido-rotate ido-rotate)
-		    (ido-cur-list ido-ignored-list))
-		(ido-trace "try all" ido-ignored-list)
-		(ido-set-matches))
-	      (when ido-matches
-		(ido-trace "found  " ido-matches)
-		(setq ido-rescan t)
-		(setq ido-process-ignore-lists-inhibit t)
-		(setq ido-text-init ido-text)
-		(setq ido-exit 'refresh)
-		(exit-minibuffer)))
-
-	  (when (and
-		 ido-rescan
-		 (not ido-matches)
-		 (memq ido-cur-item '(file dir))
-		 (not (ido-is-root-directory))
-		 (> (length contents) 1)
-		 (not (string-match "[$]" contents)))
-	    (ido-trace "merge?")
-	    (if ido-use-merged-list
-		(ido-undo-merge-work-directory contents nil)
-	      (when (and (eq ido-try-merged-list t)
-			 (numberp ido-auto-merge-work-directories-length)
-			 (= ido-auto-merge-work-directories-length 0)
-			 (not (and ido-auto-merge-inhibit-characters-regexp
-				   (string-match ido-auto-merge-inhibit-characters-regexp contents)))
-			 (not (input-pending-p)))
-		(ido-trace "\n*start timer*")
-		(setq ido-auto-merge-timer
-		      (run-with-timer ido-auto-merge-delay-time nil 'ido-initiate-auto-merge (current-buffer))))))
+	  (let ((ido-process-ignore-lists nil)
+		(ido-rotate ido-rotate)
+		(ido-cur-list ido-ignored-list))
+	    (ido-trace "try all" ido-ignored-list)
+	    (ido-set-matches))
+	  (when ido-matches
+	    (ido-trace "found  " ido-matches)
+	    (setq ido-rescan t)
+	    (setq ido-process-ignore-lists-inhibit t)
+	    (setq ido-text-init ido-text)
+	    (setq ido-exit 'refresh)
+	    (exit-minibuffer)))
+
+	(when (and
+	       ido-rescan
+	       (not ido-matches)
+	       (memq ido-cur-item '(file dir))
+	       (not (ido-is-root-directory))
+	       (> (length contents) 1)
+	       (not (string-match "[$]" contents)))
+	  (ido-trace "merge?")
+	  (if ido-use-merged-list
+	      (ido-undo-merge-work-directory contents nil)
+	    (when (and (eq ido-try-merged-list t)
+		       (numberp ido-auto-merge-work-directories-length)
+		       (= ido-auto-merge-work-directories-length 0)
+		       (not (and ido-auto-merge-inhibit-characters-regexp
+				 (string-match ido-auto-merge-inhibit-characters-regexp contents)))
+		       (not (input-pending-p)))
+	      (ido-trace "\n*start timer*")
+	      (setq ido-auto-merge-timer
+		    (run-with-timer ido-auto-merge-delay-time nil 'ido-initiate-auto-merge (current-buffer))))))
 	  
-	  (setq ido-rescan t)
-
-	  (if (and ido-use-merged-list 
-		   ido-matches
-		   (not (string-equal (car (cdr (car ido-matches))) ido-current-directory)))
-	      (progn
-		(ido-set-current-directory (car (cdr (car ido-matches))))
-		(setq ido-use-merged-list t
-		      ido-exit 'keep
-		      ido-text-init ido-text)
-		(exit-minibuffer)))
-
-	  ;; Insert the match-status information:
-	  (ido-set-common-completion)
-	  (let ((inf (ido-completions 
-		     contents
-		     minibuffer-completion-table
-		     minibuffer-completion-predicate
-		     (not minibuffer-completion-confirm))))
-	    (ido-trace "inf" inf)
-	    (insert inf))
-	  
-	  ))))
+	(setq ido-rescan t)
+
+	(if (and ido-use-merged-list 
+		 ido-matches
+		 (not (string-equal (car (cdr (car ido-matches))) ido-current-directory)))
+	    (progn
+	      (ido-set-current-directory (car (cdr (car ido-matches))))
+	      (setq ido-use-merged-list t
+		    ido-exit 'keep
+		    ido-text-init ido-text)
+	      (exit-minibuffer)))
+
+	;; Insert the match-status information:
+	(ido-set-common-completion)
+	(let ((inf (ido-completions 
+		    contents
+		    minibuffer-completion-table
+		    minibuffer-completion-predicate
+		    (not minibuffer-completion-confirm))))
+	  (ido-trace "inf" inf)
+	  (insert inf))
+	))))
 
 (defun ido-completions (name candidates predicate require-match)
   ;; Return the string that is displayed after the user's text.