comparison lisp/ido.el @ 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 1bd259d860a2
children 5a945cb7d742
comparison
equal deleted inserted replaced
49179:5dbe42c838b7 49180:b76c3354f4e7
550 Directory paths matched by one of the regexps in this list are not inserted in 550 Directory paths matched by one of the regexps in this list are not inserted in
551 the `ido-work-directory-list' list." 551 the `ido-work-directory-list' list."
552 :type '(repeat regexp) 552 :type '(repeat regexp)
553 :group 'ido) 553 :group 'ido)
554 554
555
556 (defcustom ido-enable-tramp-completion t
557 "*Non-nil means that ido shall perform tramp method and server name completion.
558 A tramp file name uses the following syntax: /method:user@host:path."
559 :type 'boolean
560 :group 'ido)
561
555 (defcustom ido-record-ftp-work-directories t 562 (defcustom ido-record-ftp-work-directories t
556 "*Non-nil means that ftp paths are recorded in work directory list." 563 "*Non-nil means that ftp paths are recorded in work directory list."
557 :type 'boolean 564 :type 'boolean
558 :group 'ido) 565 :group 'ido)
559 566
634 (defcustom ido-rotate-file-list-default nil 641 (defcustom ido-rotate-file-list-default nil
635 "*Non-nil means that `ido' will always rotate file list to get default in front." 642 "*Non-nil means that `ido' will always rotate file list to get default in front."
636 :type 'boolean 643 :type 'boolean
637 :group 'ido) 644 :group 'ido)
638 645
639 (defcustom ido-enter-single-matching-directory nil 646 (defcustom ido-enter-single-matching-directory 'slash
640 "*Automatically enter sub-directory if it is the only matching item, if non-nil. 647 "*Automatically enter sub-directory if it is the only matching item, if non-nil.
641 If value is 'slash, only enter if typing final slash, else do it always." 648 If value is 'slash, only enter if typing final slash, else do it always."
642 :type '(choice (const :tag "Never" nil) 649 :type '(choice (const :tag "Never" nil)
643 (const :tag "When typing /" slash) 650 (const :tag "When typing /" slash)
644 (other :tag "Always" t)) 651 (other :tag "Always" t))
971 retval) 978 retval)
972 979
973 (defun ido-toggle-trace (arg) 980 (defun ido-toggle-trace (arg)
974 (interactive "P") 981 (interactive "P")
975 (setq ido-trace-enable (or arg (not ido-trace-enable))) 982 (setq ido-trace-enable (or arg (not ido-trace-enable)))
983 (if ido-trace-enable
984 (message "IDO trace on"))
976 (let ((b (get-buffer " *IDO Trace*"))) 985 (let ((b (get-buffer " *IDO Trace*")))
977 (if b 986 (if b
978 (if ido-trace-enable 987 (if ido-trace-enable
979 (kill-buffer b) 988 (kill-buffer b)
980 (pop-to-buffer b t t))))) 989 (pop-to-buffer b t t)
990 (setq truncate-lines t)))))
991
992 (defun ido-is-tramp-root (&optional dir)
993 (setq dir (or dir ido-current-directory))
994 (and ido-enable-tramp-completion
995 (string-match "\\`/[^/][^/]+:\\([^/:@]+@\\)?\\'" dir)))
981 996
982 (defun ido-is-root-directory (&optional dir) 997 (defun ido-is-root-directory (&optional dir)
983 (setq dir (or dir ido-current-directory)) 998 (setq dir (or dir ido-current-directory))
984 (if (memq system-type '(windows-nt ms-dos)) 999 (or
985 (string-match "\\`[a-zA-Z]:[/\\]\\'" dir) 1000 (string-equal "/" dir)
986 (string-equal "/" dir))) 1001 (and (memq system-type '(windows-nt ms-dos))
1002 (string-match "\\`[a-zA-Z]:[/\\]\\'" dir))
1003 (if ido-enable-tramp-completion
1004 (ido-is-tramp-root dir)
1005 (string-match "\\`/[^:/][^:/]+:\\'" dir))))
987 1006
988 (defun ido-is-ftp-directory (&optional dir) 1007 (defun ido-is-ftp-directory (&optional dir)
989 (string-match "\\`/[^/:][^/:]+:/" (or dir ido-current-directory))) 1008 (string-match
1009 (if ido-enable-tramp-completion
1010 "\\`/[^/:][^/:]+:" ;; like tramp-file-name-regexp-unified, but doesn't match single drive letters
1011 "\\`/[^/:][^/:]+:/")
1012 (or dir ido-current-directory)))
990 1013
991 (defun ido-is-slow-ftp-host (&optional dir) 1014 (defun ido-is-slow-ftp-host (&optional dir)
992 (and (or ido-slow-ftp-hosts ido-slow-ftp-host-regexps) 1015 (and (or ido-slow-ftp-hosts ido-slow-ftp-host-regexps)
993 (setq dir (or dir ido-current-directory)) 1016 (setq dir (or dir ido-current-directory))
994 ;; (featurep 'ange-ftp) 1017 ;; (featurep 'ange-ftp)
995 ;; (ange-ftp-ftp-name dir) 1018 ;; (ange-ftp-ftp-name dir)
996 (string-match "\\`/\\([^/:]*@\\)?\\([^@/:][^@/:]+\\):/" dir) 1019 (string-match
1020 (if ido-enable-tramp-completion
1021 "\\`/\\([^/]+[@:]\\)*\\([^@/:][^@/:]+\\):"
1022 "\\`/\\([^/:]*@\\)?\\([^@/:][^@/:]+\\):/")
1023 dir)
997 (let ((host (substring dir (match-beginning 2) (match-end 2)))) 1024 (let ((host (substring dir (match-beginning 2) (match-end 2))))
998 (or (member host ido-slow-ftp-hosts) 1025 (or (member host ido-slow-ftp-hosts)
999 (let ((re ido-slow-ftp-host-regexps)) 1026 (let ((re ido-slow-ftp-host-regexps))
1000 (while (and re (not (string-match (car re) host))) 1027 (while (and re (not (string-match (car re) host)))
1001 (setq re (cdr re))) 1028 (setq re (cdr re)))
1012 (or (not time) 1039 (or (not time)
1013 (< (- (ido-time-stamp) time) ido-cache-ftp-work-directory-time)))) 1040 (< (- (ido-time-stamp) time) ido-cache-ftp-work-directory-time))))
1014 1041
1015 (defun ido-may-cache-directory (&optional dir) 1042 (defun ido-may-cache-directory (&optional dir)
1016 (setq dir (or dir ido-current-directory)) 1043 (setq dir (or dir ido-current-directory))
1017 (if (and (memq system-type '(windows-nt ms-dos)) 1044 (cond
1018 (string-match "\\`[a-zA-Z]:[/\\]\\'" dir)) 1045 ((and (ido-is-root-directory dir)
1019 nil 1046 (or ido-enable-tramp-completion
1020 (or (not (ido-is-ftp-directory dir)) 1047 (memq system-type '(windows-nt ms-dos))))
1021 (ido-cache-ftp-valid)))) 1048 nil)
1049 ((not (ido-is-ftp-directory dir))
1050 t)
1051 ((ido-cache-ftp-valid)
1052 t)))
1022 1053
1023 (defun ido-pp (list &optional sep) 1054 (defun ido-pp (list &optional sep)
1024 (let ((print-level nil) (eval-expression-print-level nil) 1055 (let ((print-level nil) (eval-expression-print-level nil)
1025 (print-length nil) (eval-expression-print-length nil)) 1056 (print-length nil) (eval-expression-print-length nil))
1026 (insert "\n;; ----- " (symbol-name list) " -----\n(\n ") 1057 (insert "\n;; ----- " (symbol-name list) " -----\n(\n ")
1326 ;; else if FIX-IT is non-nil, return DIR/ 1357 ;; else if FIX-IT is non-nil, return DIR/
1327 ;; else return nil. 1358 ;; else return nil.
1328 (setq dir (ido-name dir)) 1359 (setq dir (ido-name dir))
1329 (cond 1360 (cond
1330 ((string-match "/\\'" dir) dir) 1361 ((string-match "/\\'" dir) dir)
1362 ((ido-is-tramp-root dir) dir)
1331 (fix-it (concat dir "/")) 1363 (fix-it (concat dir "/"))
1332 (t nil))) 1364 (t nil)))
1333 1365
1334 (defun ido-set-current-directory (dir &optional subdir no-merge) 1366 (defun ido-set-current-directory (dir &optional subdir no-merge)
1335 ;; Set ido's current directory to DIR or DIR/SUBDIR 1367 ;; Set ido's current directory to DIR or DIR/SUBDIR
1457 ) 1489 )
1458 1490
1459 (ido-define-mode-map) 1491 (ido-define-mode-map)
1460 (setq ido-text-init initial) 1492 (setq ido-text-init initial)
1461 (while (not done) 1493 (while (not done)
1462 (ido-trace "\n_LOOP_") 1494 (ido-trace "\n_LOOP_" ido-text-init)
1463 (setq ido-exit nil) 1495 (setq ido-exit nil)
1464 (setq ido-rescan t) 1496 (setq ido-rescan t)
1465 (setq ido-rotate nil) 1497 (setq ido-rotate nil)
1466 (setq ido-text "") 1498 (setq ido-text "")
1467 (when ido-set-default-item 1499 (when ido-set-default-item
1610 (progn 1642 (progn
1611 (ido-set-current-directory d nil (eq ido-exit 'chdir)) 1643 (ido-set-current-directory d nil (eq ido-exit 'chdir))
1612 (setq ido-text-init f 1644 (setq ido-text-init f
1613 path nil)))))) 1645 path nil))))))
1614 (t 1646 (t
1615 (setq ido-text-init nil)
1616 (setq ido-text-init (read-string (concat prompt "[EDIT] ") ido-final-text)))) 1647 (setq ido-text-init (read-string (concat prompt "[EDIT] ") ido-final-text))))
1617 nil) 1648 nil)
1618 1649
1619 ((eq ido-exit 'keep) 1650 ((eq ido-exit 'keep)
1620 (setq ido-keep-item-list t)) 1651 (setq ido-keep-item-list t))
1623 (setq done t)) 1654 (setq done t))
1624 1655
1625 ((eq ido-exit 'updir) 1656 ((eq ido-exit 'updir)
1626 ;; cannot go up if already at the root-dir (Unix) or at the 1657 ;; cannot go up if already at the root-dir (Unix) or at the
1627 ;; root-dir of a certain drive (Windows or MS-DOS). 1658 ;; root-dir of a certain drive (Windows or MS-DOS).
1628 (or (ido-is-root-directory) 1659 (if (ido-is-tramp-root)
1629 (ido-set-current-directory (file-name-directory (substring ido-current-directory 0 -1)))) 1660 (when (string-match "\\`\\(/\\([^/]+[:@]\\)*\\)\\([^/]+\\)[:@]\\'" ido-current-directory)
1630 (setq ido-set-default-item t)) 1661 (setq ido-text-init (match-string 3 ido-current-directory))
1662 (ido-set-current-directory (match-string 1 ido-current-directory))
1663 (setq ido-set-default-item t))
1664 (unless (ido-is-root-directory)
1665 (ido-set-current-directory (file-name-directory (substring ido-current-directory 0 -1)))
1666 (setq ido-set-default-item t))))
1631 1667
1632 ;; Handling the require-match must be done in a better way. 1668 ;; Handling the require-match must be done in a better way.
1633 ((and require-match (not (ido-existing-item-p))) 1669 ((and require-match (not (ido-existing-item-p)))
1634 (error "must specify valid item")) 1670 (error "must specify valid item"))
1635 1671
1652 ;; cannot go up if already at the root-dir (Unix) or at the 1688 ;; cannot go up if already at the root-dir (Unix) or at the
1653 ;; root-dir of a certain drive (Windows or MS-DOS). 1689 ;; root-dir of a certain drive (Windows or MS-DOS).
1654 (or (ido-is-root-directory) 1690 (or (ido-is-root-directory)
1655 (ido-set-current-directory (file-name-directory (substring ido-current-directory 0 -1)))) 1691 (ido-set-current-directory (file-name-directory (substring ido-current-directory 0 -1))))
1656 (setq ido-set-default-item t)) 1692 (setq ido-set-default-item t))
1657 ((and (string-equal ido-current-directory "/") 1693
1658 (string-match "..:\\'" ido-selected)) ;; Ange-ftp 1694 ((and (string-match (if ido-enable-tramp-completion "..[:@]\\'" "..:\\'") ido-selected)
1659 (ido-set-current-directory "/" ido-selected) 1695 (ido-is-root-directory)) ;; Ange-ftp or Tramp
1696 (ido-set-current-directory ido-current-directory ido-selected)
1697 (ido-trace "tramp prefix" ido-selected)
1660 (if (ido-is-slow-ftp-host) 1698 (if (ido-is-slow-ftp-host)
1661 (setq ido-exit 'fallback 1699 (setq ido-exit 'fallback
1662 done t) 1700 done t)
1663 (setq ido-set-default-item t))) 1701 (setq ido-set-default-item t)))
1664
1665 ((or (string-match "[/\\][^/\\]" ido-selected) 1702 ((or (string-match "[/\\][^/\\]" ido-selected)
1666 (and (memq system-type '(windows-nt ms-dos)) 1703 (and (memq system-type '(windows-nt ms-dos))
1667 (string-match "\\`.:" ido-selected))) 1704 (string-match "\\`.:" ido-selected)))
1668 (ido-set-current-directory (file-name-directory ido-selected)) 1705 (ido-set-current-directory (file-name-directory ido-selected))
1669 (setq ido-set-default-item t)) 1706 (setq ido-set-default-item t))
1934 1971
1935 ((not ido-matches) 1972 ((not ido-matches)
1936 (when ido-completion-buffer 1973 (when ido-completion-buffer
1937 (call-interactively (setq this-command ido-cannot-complete-command)))) 1974 (call-interactively (setq this-command ido-cannot-complete-command))))
1938 1975
1939 ((= 1 (length ido-matches)) 1976 ((and (= 1 (length ido-matches))
1977 (not (and ido-enable-tramp-completion
1978 (string-equal ido-current-directory "/")
1979 (string-match "..[@:]\\'" (car ido-matches)))))
1940 ;; only one choice, so select it. 1980 ;; only one choice, so select it.
1941 (exit-minibuffer)) 1981 (exit-minibuffer))
1942 1982
1943 (t ;; else there could be some completions 1983 (t ;; else there could be some completions
1944 (setq res ido-common-match-string) 1984 (setq res ido-common-match-string)
2580 items) 2620 items)
2581 (if ido-temp-list 2621 (if ido-temp-list
2582 (nconc ido-temp-list items) 2622 (nconc ido-temp-list items)
2583 (setq ido-temp-list items))) 2623 (setq ido-temp-list items)))
2584 2624
2625 (defun ido-file-name-all-completions1 (dir)
2626 (if (and ido-enable-tramp-completion
2627 (string-match "\\`/\\([^/:]+:\\([^/:@]+@\\)?\\)\\'" dir))
2628
2629 ;; Trick tramp's file-name-all-completions handler to DTRT, as it
2630 ;; has some pretty obscure requirements. This seems to work...
2631 ;; /ftp: => (f-n-a-c "/ftp:" "")
2632 ;; /ftp:kfs: => (f-n-a-c "" "/ftp:kfs:")
2633 ;; /ftp:kfs@ => (f-n-a-c "ftp:kfs@" "/")
2634 ;; /ftp:kfs@kfs: => (f-n-a-c "" "/ftp:kfs@kfs:")
2635 ;; Currently no attempt is made to handle multi: stuff.
2636
2637 (let* ((prefix (match-string 1 dir))
2638 (user-flag (match-beginning 2))
2639 (len (and prefix (length prefix)))
2640 compl)
2641 (if user-flag
2642 (setq dir (substring dir 1)))
2643 (require 'tramp nil t)
2644 (ido-trace "tramp complete" dir)
2645 (setq compl (file-name-all-completions dir (if user-flag "/" "")))
2646 (if (> len 0)
2647 (mapcar (lambda (c) (substring c len)) compl)
2648 compl))
2649 (file-name-all-completions "" dir)))
2650
2585 (defun ido-file-name-all-completions (dir) 2651 (defun ido-file-name-all-completions (dir)
2586 ;; Return name of all files in DIR 2652 ;; Return name of all files in DIR
2587 ;; Uses and updates ido-dir-file-cache 2653 ;; Uses and updates ido-dir-file-cache
2588 (if (and (numberp ido-max-dir-file-cache) (> ido-max-dir-file-cache 0) 2654 (if (and (numberp ido-max-dir-file-cache) (> ido-max-dir-file-cache 0)
2589 (stringp dir) (> (length dir) 0) 2655 (stringp dir) (> (length dir) 0)
2606 cached nil))) 2672 cached nil)))
2607 (unless cached 2673 (unless cached
2608 (if (and ftp (file-readable-p dir)) 2674 (if (and ftp (file-readable-p dir))
2609 (setq mtime (cons 'ftp (ido-time-stamp)))) 2675 (setq mtime (cons 'ftp (ido-time-stamp))))
2610 (if mtime 2676 (if mtime
2611 (setq cached (cons dir (cons mtime (file-name-all-completions "" dir))) 2677 (setq cached (cons dir (cons mtime (ido-file-name-all-completions1 dir)))
2612 ido-dir-file-cache (cons cached ido-dir-file-cache))) 2678 ido-dir-file-cache (cons cached ido-dir-file-cache)))
2613 (if (> (length ido-dir-file-cache) ido-max-dir-file-cache) 2679 (if (> (length ido-dir-file-cache) ido-max-dir-file-cache)
2614 (setcdr (nthcdr (1- ido-max-dir-file-cache) ido-dir-file-cache) nil))) 2680 (setcdr (nthcdr (1- ido-max-dir-file-cache) ido-dir-file-cache) nil)))
2615 (and cached 2681 (and cached
2616 (cdr (cdr cached)))) 2682 (cdr (cdr cached))))
2617 (file-name-all-completions "" dir))) 2683 (ido-file-name-all-completions1 dir)))
2618 2684
2619 (defun ido-remove-cached-dir (dir) 2685 (defun ido-remove-cached-dir (dir)
2620 ;; Remove dir from ido-dir-file-cache 2686 ;; Remove dir from ido-dir-file-cache
2621 (if (and ido-dir-file-cache 2687 (if (and ido-dir-file-cache
2622 (stringp dir) (> (length dir) 0)) 2688 (stringp dir) (> (length dir) 0))
2626 2692
2627 2693
2628 (defun ido-make-file-list1 (dir &optional merged) 2694 (defun ido-make-file-list1 (dir &optional merged)
2629 ;; Return list of non-ignored files in DIR 2695 ;; Return list of non-ignored files in DIR
2630 ;; If MERGED is non-nil, each file is cons'ed with DIR 2696 ;; If MERGED is non-nil, each file is cons'ed with DIR
2631 (and (file-directory-p dir) 2697 (and (or (ido-is-tramp-root dir) (file-directory-p dir))
2632 (delq nil 2698 (delq nil
2633 (mapcar 2699 (mapcar
2634 (lambda (name) 2700 (lambda (name)
2635 (if (not (ido-ignore-item-p name ido-ignore-files t)) 2701 (if (not (ido-ignore-item-p name ido-ignore-files t))
2636 (if merged (cons name dir) name))) 2702 (if merged (cons name dir) name)))
2674 ido-temp-list)) 2740 ido-temp-list))
2675 2741
2676 (defun ido-make-dir-list1 (dir &optional merged) 2742 (defun ido-make-dir-list1 (dir &optional merged)
2677 ;; Return list of non-ignored subdirs in DIR 2743 ;; Return list of non-ignored subdirs in DIR
2678 ;; If MERGED is non-nil, each subdir is cons'ed with DIR 2744 ;; If MERGED is non-nil, each subdir is cons'ed with DIR
2679 (and (file-directory-p dir) 2745 (and (or (ido-is-tramp-root dir) (file-directory-p dir))
2680 (delq nil 2746 (delq nil
2681 (mapcar 2747 (mapcar
2682 (lambda (name) 2748 (lambda (name)
2683 (and (ido-final-slash name) (not (ido-ignore-item-p name ido-ignore-directories)) 2749 (and (ido-final-slash name) (not (ido-ignore-item-p name ido-ignore-directories))
2684 (if merged (cons name dir) name))) 2750 (if merged (cons name dir) name)))
2748 ;;; FIND MATCHING ITEMS 2814 ;;; FIND MATCHING ITEMS
2749 2815
2750 (defun ido-set-matches1 (items &optional do-full) 2816 (defun ido-set-matches1 (items &optional do-full)
2751 ;; Return list of matches in items 2817 ;; Return list of matches in items
2752 (let* ((case-fold-search ido-case-fold) 2818 (let* ((case-fold-search ido-case-fold)
2753 (rexq (if ido-enable-regexp ido-text (regexp-quote ido-text))) 2819 (slash (and (not ido-enable-prefix) (ido-final-slash ido-text)))
2820 (text (if slash (substring ido-text 0 -1) ido-text))
2821 (rexq (concat (if ido-enable-regexp text (regexp-quote text)) (if slash ".*/" "")))
2754 (re (if ido-enable-prefix (concat "\\`" rexq) rexq)) 2822 (re (if ido-enable-prefix (concat "\\`" rexq) rexq))
2755 (full-re (and do-full (not ido-enable-regexp) (not (string-match "\$\\'" re)) 2823 (full-re (and do-full (not ido-enable-regexp) (not (string-match "\$\\'" re))
2756 (concat "\\`" re "\\'"))) 2824 (concat "\\`" re "\\'")))
2757 (prefix-re (and full-re (not ido-enable-prefix) 2825 (prefix-re (and full-re (not ido-enable-prefix)
2758 (concat "\\`" rexq))) 2826 (concat "\\`" rexq)))
3302 ;; Find matching files and display a list in the minibuffer. 3370 ;; Find matching files and display a list in the minibuffer.
3303 ;; Copied from `icomplete-exhibit' with two changes: 3371 ;; Copied from `icomplete-exhibit' with two changes:
3304 ;; 1. It prints a default file name when there is no text yet entered. 3372 ;; 1. It prints a default file name when there is no text yet entered.
3305 ;; 2. It calls my completion routine rather than the standard completion. 3373 ;; 2. It calls my completion routine rather than the standard completion.
3306 3374
3307 (if (= ido-use-mycompletion-depth (minibuffer-depth)) 3375 (when (= ido-use-mycompletion-depth (minibuffer-depth))
3308 (let ((contents (buffer-substring-no-properties (minibuffer-prompt-end) (point-max))) 3376 (let ((contents (buffer-substring-no-properties (minibuffer-prompt-end) (point-max)))
3309 (buffer-undo-list t) 3377 (buffer-undo-list t)
3310 try-single-dir-match) 3378 try-single-dir-match
3311 3379 refresh)
3312 (ido-trace "\nexhibit" this-command) 3380
3313 (ido-trace "dir" ido-current-directory) 3381 (ido-trace "\nexhibit" this-command)
3314 (ido-trace "contents" contents) 3382 (ido-trace "dir" ido-current-directory)
3315 (ido-trace "list" ido-cur-list) 3383 (ido-trace "contents" contents)
3316 (ido-trace "matches" ido-matches) 3384 (ido-trace "list" ido-cur-list)
3317 (ido-trace "rescan" ido-rescan) 3385 (ido-trace "matches" ido-matches)
3318 3386 (ido-trace "rescan" ido-rescan)
3319 (save-excursion 3387
3320 (goto-char (point-max)) 3388 (save-excursion
3321 ;; Register the end of input, so we know where the extra stuff (match-status info) begins: 3389 (goto-char (point-max))
3322 (if (not (boundp 'ido-eoinput)) 3390 ;; Register the end of input, so we know where the extra stuff (match-status info) begins:
3323 ;; In case it got wiped out by major mode business: 3391 (unless (boundp 'ido-eoinput)
3324 (make-local-variable 'ido-eoinput)) 3392 ;; In case it got wiped out by major mode business:
3325 (setq ido-eoinput (point)) 3393 (make-local-variable 'ido-eoinput))
3326 3394 (setq ido-eoinput (point))
3327 ;; Handle explicit directory changes 3395
3328 (and 3396 ;; Handle explicit directory changes
3329 (memq ido-cur-item '(file dir)) 3397 (cond
3330 (> (length contents) 1) 3398 ((eq ido-cur-item 'buffer)
3399 )
3400
3401 ((= (length contents) 0)
3402 )
3403
3404 ((= (length contents) 1)
3405 (when (and (ido-is-tramp-root) (string-equal contents "/"))
3406 (ido-set-current-directory ido-current-directory contents)
3407 (setq refresh t))
3408 )
3409
3410 ((and (string-match (if ido-enable-tramp-completion "..[:@]\\'" "..:\\'") contents)
3411 (ido-is-root-directory)) ;; Ange-ftp or tramp
3412 (ido-set-current-directory ido-current-directory contents)
3413 (when (ido-is-slow-ftp-host)
3414 (setq ido-exit 'fallback)
3415 (exit-minibuffer))
3416 (setq refresh t))
3417
3418 ((ido-final-slash contents) ;; xxx/
3419 (ido-trace "final slash" contents)
3420 (cond
3421 ((string-equal contents "~/")
3422 (ido-set-current-home)
3423 (setq refresh t))
3424 ((string-equal contents "../")
3425 (ido-up-directory t)
3426 (setq refresh t))
3427 ((string-equal contents "./")
3428 (setq refresh t))
3429 ((string-match "\\`~[a-zA-Z0-9]+/\\'" contents)
3430 (ido-trace "new home" contents)
3431 (ido-set-current-home contents)
3432 (setq refresh t))
3433 ((string-match "[$][A-Za-z0-9_]+/\\'" contents)
3434 (let ((exp (condition-case ()
3435 (expand-file-name
3436 (substitute-in-file-name (substring contents 0 -1))
3437 ido-current-directory)
3438 (error nil))))
3439 (ido-trace contents exp)
3440 (when (and exp (file-directory-p exp))
3441 (ido-set-current-directory (file-name-directory exp))
3442 (setq ido-text-init (file-name-nondirectory exp))
3443 (setq refresh t))))
3444 ((and (memq system-type '(windows-nt ms-dos))
3445 (string-equal (substring contents 1) ":/"))
3446 (ido-set-current-directory (file-name-directory contents))
3447 (setq refresh t))
3448 ((string-equal (substring contents -2 -1) "/")
3449 (ido-set-current-directory
3450 (if (memq system-type '(windows-nt ms-dos))
3451 (expand-file-name "/" ido-current-directory)
3452 "/"))
3453 (setq refresh t))
3454 (t
3455 (ido-trace "try single dir")
3456 (setq try-single-dir-match t))))
3457
3458 ((and (string-equal (substring contents -2 -1) "/")
3459 (not (string-match "[$]" contents)))
3460 (ido-set-current-directory
3331 (cond 3461 (cond
3332 ((ido-final-slash contents) ;; xxx/ 3462 ((= (length contents) 2)
3333 (ido-trace "final slash" contents) 3463 "/")
3334 (cond 3464 (ido-matches
3335 ((string-equal contents "~/")
3336 (ido-set-current-home)
3337 t)
3338 ((string-equal contents "../")
3339 (ido-up-directory t)
3340 t)
3341 ((string-equal contents "./")
3342 t)
3343 ((string-match contents "\\`~[a-zA-Z0-9]/\\'")
3344 (ido-set-current-home contents)
3345 t)
3346 ((string-match "[$][A-Za-z0-9_]+/\\'" contents)
3347 (let ((exp (condition-case ()
3348 (expand-file-name
3349 (substitute-in-file-name (substring contents 0 -1))
3350 ido-current-directory)
3351 (error nil))))
3352 (ido-trace contents exp)
3353 (if (and exp (file-directory-p exp))
3354 (progn
3355 (ido-set-current-directory (file-name-directory exp))
3356 (setq ido-text-init (file-name-nondirectory exp))
3357 t)
3358 nil)))
3359 ((and (memq system-type '(windows-nt ms-dos))
3360 (string-equal (substring contents 1) ":/"))
3361 (ido-set-current-directory (file-name-directory contents))
3362 t)
3363 ((string-equal (substring contents -2 -1) "/")
3364 (ido-set-current-directory
3365 (if (memq system-type '(windows-nt ms-dos))
3366 (expand-file-name "/" ido-current-directory)
3367 "/"))
3368 t)
3369 (t
3370 (setq try-single-dir-match t)
3371 nil)))
3372
3373 ((and (string-equal ido-current-directory "/")
3374 (string-match "..:\\'" contents)) ;; Ange-ftp
3375 (ido-set-current-directory "/" contents)
3376 (when (ido-is-slow-ftp-host)
3377 (setq ido-exit 'fallback)
3378 (exit-minibuffer))
3379 t)
3380
3381 ((and (string-equal (substring contents -2 -1) "/")
3382 (not (string-match "[$]" contents)))
3383 (ido-set-current-directory
3384 (cond
3385 ((= (length contents) 2)
3386 "/")
3387 (ido-matches
3388 (concat ido-current-directory (car ido-matches)))
3389 (t
3390 (concat ido-current-directory (substring contents 0 -1)))))
3391 (setq ido-text-init (substring contents -1))
3392 t)
3393
3394 ((and (not ido-use-merged-list)
3395 (not (ido-final-slash contents))
3396 (eq ido-try-merged-list t)
3397 (numberp ido-auto-merge-work-directories-length)
3398 (> ido-auto-merge-work-directories-length 0)
3399 (= (length contents) ido-auto-merge-work-directories-length)
3400 (not (and ido-auto-merge-inhibit-characters-regexp
3401 (string-match ido-auto-merge-inhibit-characters-regexp contents)))
3402 (not (input-pending-p)))
3403 (setq ido-use-merged-list 'auto
3404 ido-text-init contents
3405 ido-rotate-temp t)
3406 t))
3407 (progn
3408 (ido-trace "refresh on /" ido-text-init)
3409 (setq ido-exit 'refresh)
3410 (exit-minibuffer)))
3411
3412 ;; Update the list of matches
3413 (setq ido-text contents)
3414 (ido-set-matches)
3415 (ido-trace "new " ido-matches)
3416
3417 (when (and ido-enter-single-matching-directory
3418 ido-matches
3419 (null (cdr ido-matches))
3420 (ido-final-slash (car ido-matches))
3421 (or try-single-dir-match
3422 (eq ido-enter-single-matching-directory t)))
3423 (ido-trace "single match" (car ido-matches))
3424 (ido-set-current-directory
3425 (concat ido-current-directory (car ido-matches))) 3465 (concat ido-current-directory (car ido-matches)))
3426 (setq ido-exit 'refresh) 3466 (t
3427 (exit-minibuffer)) 3467 (concat ido-current-directory (substring contents 0 -1)))))
3428 3468 (setq ido-text-init (substring contents -1))
3429 (when (and (not ido-matches) 3469 (setq refresh t))
3430 ; ido-rescan 3470
3471 ((and (not ido-use-merged-list)
3472 (not (ido-final-slash contents))
3473 (eq ido-try-merged-list t)
3474 (numberp ido-auto-merge-work-directories-length)
3475 (> ido-auto-merge-work-directories-length 0)
3476 (= (length contents) ido-auto-merge-work-directories-length)
3477 (not (and ido-auto-merge-inhibit-characters-regexp
3478 (string-match ido-auto-merge-inhibit-characters-regexp contents)))
3479 (not (input-pending-p)))
3480 (setq ido-use-merged-list 'auto
3481 ido-text-init contents
3482 ido-rotate-temp t)
3483 (setq refresh t))
3484
3485 (t nil))
3486
3487 (when refresh
3488 (ido-trace "refresh on /" ido-text-init)
3489 (setq ido-exit 'refresh)
3490 (exit-minibuffer))
3491
3492 ;; Update the list of matches
3493 (setq ido-text contents)
3494 (ido-set-matches)
3495 (ido-trace "new " ido-matches)
3496
3497 (when (and ido-enter-single-matching-directory
3498 ido-matches
3499 (null (cdr ido-matches))
3500 (ido-final-slash (car ido-matches))
3501 (or try-single-dir-match
3502 (eq ido-enter-single-matching-directory t)))
3503 (ido-trace "single match" (car ido-matches))
3504 (ido-set-current-directory
3505 (concat ido-current-directory (car ido-matches)))
3506 (setq ido-exit 'refresh)
3507 (exit-minibuffer))
3508
3509 (when (and (not ido-matches)
3510 ;; ido-rescan ?
3431 ido-process-ignore-lists 3511 ido-process-ignore-lists
3432 ido-ignored-list) 3512 ido-ignored-list)
3433 (let ((ido-process-ignore-lists nil) 3513 (let ((ido-process-ignore-lists nil)
3434 (ido-rotate ido-rotate) 3514 (ido-rotate ido-rotate)
3435 (ido-cur-list ido-ignored-list)) 3515 (ido-cur-list ido-ignored-list))
3436 (ido-trace "try all" ido-ignored-list) 3516 (ido-trace "try all" ido-ignored-list)
3437 (ido-set-matches)) 3517 (ido-set-matches))
3438 (when ido-matches 3518 (when ido-matches
3439 (ido-trace "found " ido-matches) 3519 (ido-trace "found " ido-matches)
3440 (setq ido-rescan t) 3520 (setq ido-rescan t)
3441 (setq ido-process-ignore-lists-inhibit t) 3521 (setq ido-process-ignore-lists-inhibit t)
3442 (setq ido-text-init ido-text) 3522 (setq ido-text-init ido-text)
3443 (setq ido-exit 'refresh) 3523 (setq ido-exit 'refresh)
3444 (exit-minibuffer))) 3524 (exit-minibuffer)))
3445 3525
3446 (when (and 3526 (when (and
3447 ido-rescan 3527 ido-rescan
3448 (not ido-matches) 3528 (not ido-matches)
3449 (memq ido-cur-item '(file dir)) 3529 (memq ido-cur-item '(file dir))
3450 (not (ido-is-root-directory)) 3530 (not (ido-is-root-directory))
3451 (> (length contents) 1) 3531 (> (length contents) 1)
3452 (not (string-match "[$]" contents))) 3532 (not (string-match "[$]" contents)))
3453 (ido-trace "merge?") 3533 (ido-trace "merge?")
3454 (if ido-use-merged-list 3534 (if ido-use-merged-list
3455 (ido-undo-merge-work-directory contents nil) 3535 (ido-undo-merge-work-directory contents nil)
3456 (when (and (eq ido-try-merged-list t) 3536 (when (and (eq ido-try-merged-list t)
3457 (numberp ido-auto-merge-work-directories-length) 3537 (numberp ido-auto-merge-work-directories-length)
3458 (= ido-auto-merge-work-directories-length 0) 3538 (= ido-auto-merge-work-directories-length 0)
3459 (not (and ido-auto-merge-inhibit-characters-regexp 3539 (not (and ido-auto-merge-inhibit-characters-regexp
3460 (string-match ido-auto-merge-inhibit-characters-regexp contents))) 3540 (string-match ido-auto-merge-inhibit-characters-regexp contents)))
3461 (not (input-pending-p))) 3541 (not (input-pending-p)))
3462 (ido-trace "\n*start timer*") 3542 (ido-trace "\n*start timer*")
3463 (setq ido-auto-merge-timer 3543 (setq ido-auto-merge-timer
3464 (run-with-timer ido-auto-merge-delay-time nil 'ido-initiate-auto-merge (current-buffer)))))) 3544 (run-with-timer ido-auto-merge-delay-time nil 'ido-initiate-auto-merge (current-buffer))))))
3465 3545
3466 (setq ido-rescan t) 3546 (setq ido-rescan t)
3467 3547
3468 (if (and ido-use-merged-list 3548 (if (and ido-use-merged-list
3469 ido-matches 3549 ido-matches
3470 (not (string-equal (car (cdr (car ido-matches))) ido-current-directory))) 3550 (not (string-equal (car (cdr (car ido-matches))) ido-current-directory)))
3471 (progn 3551 (progn
3472 (ido-set-current-directory (car (cdr (car ido-matches)))) 3552 (ido-set-current-directory (car (cdr (car ido-matches))))
3473 (setq ido-use-merged-list t 3553 (setq ido-use-merged-list t
3474 ido-exit 'keep 3554 ido-exit 'keep
3475 ido-text-init ido-text) 3555 ido-text-init ido-text)
3476 (exit-minibuffer))) 3556 (exit-minibuffer)))
3477 3557
3478 ;; Insert the match-status information: 3558 ;; Insert the match-status information:
3479 (ido-set-common-completion) 3559 (ido-set-common-completion)
3480 (let ((inf (ido-completions 3560 (let ((inf (ido-completions
3481 contents 3561 contents
3482 minibuffer-completion-table 3562 minibuffer-completion-table
3483 minibuffer-completion-predicate 3563 minibuffer-completion-predicate
3484 (not minibuffer-completion-confirm)))) 3564 (not minibuffer-completion-confirm))))
3485 (ido-trace "inf" inf) 3565 (ido-trace "inf" inf)
3486 (insert inf)) 3566 (insert inf))
3487 3567 ))))
3488 ))))
3489 3568
3490 (defun ido-completions (name candidates predicate require-match) 3569 (defun ido-completions (name candidates predicate require-match)
3491 ;; Return the string that is displayed after the user's text. 3570 ;; Return the string that is displayed after the user's text.
3492 ;; Modified from `icomplete-completions'. 3571 ;; Modified from `icomplete-completions'.
3493 3572