diff options
| -rw-r--r-- | lisp/ido.el | 119 |
1 files changed, 73 insertions, 46 deletions
diff --git a/lisp/ido.el b/lisp/ido.el index 57736ae7d26..165142ea222 100644 --- a/lisp/ido.el +++ b/lisp/ido.el | |||
| @@ -685,16 +685,17 @@ Obsolete. Set 3rd element of `ido-decorations' instead." | |||
| 685 | :type '(choice string (const nil)) | 685 | :type '(choice string (const nil)) |
| 686 | :group 'ido) | 686 | :group 'ido) |
| 687 | 687 | ||
| 688 | (defcustom ido-decorations '( "{" "}" " | " " | ..." "[" "]" " [No match]" " [Matched]") | 688 | (defcustom ido-decorations '( "{" "}" " | " " | ..." "[" "]" " [No match]" " [Matched]" " [Not readable]") |
| 689 | "*List of strings used by ido to display the alternatives in the minibuffer. | 689 | "*List of strings used by ido to display the alternatives in the minibuffer. |
| 690 | There are 8 elements in this list, each is a pair of strings: | 690 | There are 9 elements in this list: |
| 691 | 1st and 2nd elements are used as brackets around the prospect list, | 691 | 1st and 2nd elements are used as brackets around the prospect list, |
| 692 | 3rd element is the separator between prospects (ignored if ido-separator is set), | 692 | 3rd element is the separator between prospects (ignored if ido-separator is set), |
| 693 | 4th element is the string inserted at the end of a truncated list of prospects, | 693 | 4th element is the string inserted at the end of a truncated list of prospects, |
| 694 | 5th and 6th elements are used as brackets around the common match string which | 694 | 5th and 6th elements are used as brackets around the common match string which |
| 695 | can be completed using TAB, | 695 | can be completed using TAB, |
| 696 | 7th element is the string displayed when there are a no matches, and | 696 | 7th element is the string displayed when there are a no matches, and |
| 697 | 8th element displayed if there is a single match (and faces are not used)." | 697 | 8th element is displayed if there is a single match (and faces are not used). |
| 698 | 9th element is displayed when the current directory is non-readable." | ||
| 698 | :type '(repeat string) | 699 | :type '(repeat string) |
| 699 | :group 'ido) | 700 | :group 'ido) |
| 700 | 701 | ||
| @@ -931,6 +932,9 @@ it doesn't interfere with other minibuffer usage.") | |||
| 931 | ;; `ido-cur-list'. It is in no specific order. | 932 | ;; `ido-cur-list'. It is in no specific order. |
| 932 | (defvar ido-ignored-list) | 933 | (defvar ido-ignored-list) |
| 933 | 934 | ||
| 935 | ;; Remember if current directory is non-readable (so we cannot do completion). | ||
| 936 | (defvar ido-directory-nonreadable) | ||
| 937 | |||
| 934 | ;; Keep current item list if non-nil. | 938 | ;; Keep current item list if non-nil. |
| 935 | (defvar ido-keep-item-list) | 939 | (defvar ido-keep-item-list) |
| 936 | 940 | ||
| @@ -1406,6 +1410,7 @@ This function also adds a hook to the minibuffer." | |||
| 1406 | (setq ido-current-directory dir) | 1410 | (setq ido-current-directory dir) |
| 1407 | (if (get-buffer ido-completion-buffer) | 1411 | (if (get-buffer ido-completion-buffer) |
| 1408 | (kill-buffer ido-completion-buffer)) | 1412 | (kill-buffer ido-completion-buffer)) |
| 1413 | (setq ido-directory-nonreadable (not (file-readable-p dir))) | ||
| 1409 | t)) | 1414 | t)) |
| 1410 | 1415 | ||
| 1411 | (defun ido-set-current-home (&optional dir) | 1416 | (defun ido-set-current-home (&optional dir) |
| @@ -1812,7 +1817,8 @@ PROMPT is the prompt to give to the user. DEFAULT if given is the default | |||
| 1812 | buffer to be selected, which will go to the front of the list. | 1817 | buffer to be selected, which will go to the front of the list. |
| 1813 | If REQUIRE-MATCH is non-nil, an existing-buffer must be selected. | 1818 | If REQUIRE-MATCH is non-nil, an existing-buffer must be selected. |
| 1814 | If INITIAL is non-nil, it specifies the initial input string." | 1819 | If INITIAL is non-nil, it specifies the initial input string." |
| 1815 | (let ((ido-current-directory nil)) | 1820 | (let ((ido-current-directory nil) |
| 1821 | (ido-directory-nonreadable nil)) | ||
| 1816 | (ido-read-internal 'buffer prompt 'ido-buffer-history default require-match initial))) | 1822 | (ido-read-internal 'buffer prompt 'ido-buffer-history default require-match initial))) |
| 1817 | 1823 | ||
| 1818 | (defun ido-record-work-directory (&optional dir) | 1824 | (defun ido-record-work-directory (&optional dir) |
| @@ -1851,12 +1857,18 @@ If INITIAL is non-nil, it specifies the initial input string." | |||
| 1851 | (if (> (length ido-work-file-list) ido-max-work-file-list) | 1857 | (if (> (length ido-work-file-list) ido-max-work-file-list) |
| 1852 | (setcdr (nthcdr (1- ido-max-work-file-list) ido-work-file-list) nil)))) | 1858 | (setcdr (nthcdr (1- ido-max-work-file-list) ido-work-file-list) nil)))) |
| 1853 | 1859 | ||
| 1860 | (defun ido-expand-directory (dir) | ||
| 1861 | ;; Expand DIR or use DEFAULT-DIRECTORY if nil. | ||
| 1862 | ;; Add final slash to result in case it was missing from DEFAULT-DIRECTORY. | ||
| 1863 | (ido-final-slash (expand-file-name (or dir default-directory)) t)) | ||
| 1864 | |||
| 1854 | (defun ido-file-internal (method &optional fallback default prompt item initial) | 1865 | (defun ido-file-internal (method &optional fallback default prompt item initial) |
| 1855 | ;; Internal function for ido-find-file and friends | 1866 | ;; Internal function for ido-find-file and friends |
| 1856 | (unless item | 1867 | (unless item |
| 1857 | (setq item 'file)) | 1868 | (setq item 'file)) |
| 1858 | (let ((ido-current-directory (expand-file-name (or default default-directory))) | 1869 | (let* ((ido-current-directory (ido-expand-directory default)) |
| 1859 | filename) | 1870 | (ido-directory-nonreadable (not (file-readable-p ido-current-directory))) |
| 1871 | filename) | ||
| 1860 | 1872 | ||
| 1861 | (cond | 1873 | (cond |
| 1862 | ((or (not ido-mode) (ido-is-slow-ftp-host)) | 1874 | ((or (not ido-mode) (ido-is-slow-ftp-host)) |
| @@ -2693,30 +2705,33 @@ for first matching file." | |||
| 2693 | (setq ido-temp-list items))) | 2705 | (setq ido-temp-list items))) |
| 2694 | 2706 | ||
| 2695 | (defun ido-file-name-all-completions1 (dir) | 2707 | (defun ido-file-name-all-completions1 (dir) |
| 2696 | (if (and ido-enable-tramp-completion | 2708 | (cond |
| 2697 | (string-match "\\`/\\([^/:]+:\\([^/:@]+@\\)?\\)\\'" dir)) | 2709 | ((not (file-readable-p dir)) '()) |
| 2698 | 2710 | ((and ido-enable-tramp-completion | |
| 2699 | ;; Trick tramp's file-name-all-completions handler to DTRT, as it | 2711 | (string-match "\\`/\\([^/:]+:\\([^/:@]+@\\)?\\)\\'" dir)) |
| 2700 | ;; has some pretty obscure requirements. This seems to work... | 2712 | |
| 2701 | ;; /ftp: => (f-n-a-c "/ftp:" "") | 2713 | ;; Trick tramp's file-name-all-completions handler to DTRT, as it |
| 2702 | ;; /ftp:kfs: => (f-n-a-c "" "/ftp:kfs:") | 2714 | ;; has some pretty obscure requirements. This seems to work... |
| 2703 | ;; /ftp:kfs@ => (f-n-a-c "ftp:kfs@" "/") | 2715 | ;; /ftp: => (f-n-a-c "/ftp:" "") |
| 2704 | ;; /ftp:kfs@kfs: => (f-n-a-c "" "/ftp:kfs@kfs:") | 2716 | ;; /ftp:kfs: => (f-n-a-c "" "/ftp:kfs:") |
| 2705 | ;; Currently no attempt is made to handle multi: stuff. | 2717 | ;; /ftp:kfs@ => (f-n-a-c "ftp:kfs@" "/") |
| 2706 | 2718 | ;; /ftp:kfs@kfs: => (f-n-a-c "" "/ftp:kfs@kfs:") | |
| 2707 | (let* ((prefix (match-string 1 dir)) | 2719 | ;; Currently no attempt is made to handle multi: stuff. |
| 2708 | (user-flag (match-beginning 2)) | 2720 | |
| 2709 | (len (and prefix (length prefix))) | 2721 | (let* ((prefix (match-string 1 dir)) |
| 2710 | compl) | 2722 | (user-flag (match-beginning 2)) |
| 2711 | (if user-flag | 2723 | (len (and prefix (length prefix))) |
| 2712 | (setq dir (substring dir 1))) | 2724 | compl) |
| 2713 | (require 'tramp nil t) | 2725 | (if user-flag |
| 2714 | (ido-trace "tramp complete" dir) | 2726 | (setq dir (substring dir 1))) |
| 2715 | (setq compl (file-name-all-completions dir (if user-flag "/" ""))) | 2727 | (require 'tramp nil t) |
| 2716 | (if (> len 0) | 2728 | (ido-trace "tramp complete" dir) |
| 2717 | (mapcar (lambda (c) (substring c len)) compl) | 2729 | (setq compl (file-name-all-completions dir (if user-flag "/" ""))) |
| 2718 | compl)) | 2730 | (if (> len 0) |
| 2719 | (file-name-all-completions "" dir))) | 2731 | (mapcar (lambda (c) (substring c len)) compl) |
| 2732 | compl))) | ||
| 2733 | (t | ||
| 2734 | (file-name-all-completions "" dir)))) | ||
| 2720 | 2735 | ||
| 2721 | (defun ido-file-name-all-completions (dir) | 2736 | (defun ido-file-name-all-completions (dir) |
| 2722 | ;; Return name of all files in DIR | 2737 | ;; Return name of all files in DIR |
| @@ -3518,6 +3533,11 @@ For details of keybindings, do `\\[describe-function] ido-find-file'." | |||
| 3518 | (expand-file-name "/" ido-current-directory) | 3533 | (expand-file-name "/" ido-current-directory) |
| 3519 | "/")) | 3534 | "/")) |
| 3520 | (setq refresh t)) | 3535 | (setq refresh t)) |
| 3536 | ((and ido-directory-nonreadable | ||
| 3537 | (file-directory-p (concat ido-current-directory (file-name-directory contents)))) | ||
| 3538 | (ido-set-current-directory | ||
| 3539 | (concat ido-current-directory (file-name-directory contents))) | ||
| 3540 | (setq refresh t)) | ||
| 3521 | (t | 3541 | (t |
| 3522 | (ido-trace "try single dir") | 3542 | (ido-trace "try single dir") |
| 3523 | (setq try-single-dir-match t)))) | 3543 | (setq try-single-dir-match t)))) |
| @@ -3574,6 +3594,7 @@ For details of keybindings, do `\\[describe-function] ido-find-file'." | |||
| 3574 | (exit-minibuffer)) | 3594 | (exit-minibuffer)) |
| 3575 | 3595 | ||
| 3576 | (when (and (not ido-matches) | 3596 | (when (and (not ido-matches) |
| 3597 | (not ido-directory-nonreadable) | ||
| 3577 | ;; ido-rescan ? | 3598 | ;; ido-rescan ? |
| 3578 | ido-process-ignore-lists | 3599 | ido-process-ignore-lists |
| 3579 | ido-ignored-list) | 3600 | ido-ignored-list) |
| @@ -3596,7 +3617,8 @@ For details of keybindings, do `\\[describe-function] ido-find-file'." | |||
| 3596 | (memq ido-cur-item '(file dir)) | 3617 | (memq ido-cur-item '(file dir)) |
| 3597 | (not (ido-is-root-directory)) | 3618 | (not (ido-is-root-directory)) |
| 3598 | (> (length contents) 1) | 3619 | (> (length contents) 1) |
| 3599 | (not (string-match "[$]" contents))) | 3620 | (not (string-match "[$]" contents)) |
| 3621 | (not ido-directory-nonreadable)) | ||
| 3600 | (ido-trace "merge?") | 3622 | (ido-trace "merge?") |
| 3601 | (if ido-use-merged-list | 3623 | (if ido-use-merged-list |
| 3602 | (ido-undo-merge-work-directory contents nil) | 3624 | (ido-undo-merge-work-directory contents nil) |
| @@ -3658,9 +3680,12 @@ For details of keybindings, do `\\[describe-function] ido-find-file'." | |||
| 3658 | (setq comps (cons first (cdr comps))))) | 3680 | (setq comps (cons first (cdr comps))))) |
| 3659 | 3681 | ||
| 3660 | (cond ((null comps) | 3682 | (cond ((null comps) |
| 3661 | (if ido-report-no-match | 3683 | (cond |
| 3662 | (nth 6 ido-decorations) ;; [No Match] | 3684 | (ido-directory-nonreadable |
| 3663 | "")) | 3685 | (or (nth 8 ido-decorations) " [Not readable]")) |
| 3686 | (ido-report-no-match | ||
| 3687 | (nth 6 ido-decorations)) ;; [No match] | ||
| 3688 | (t ""))) | ||
| 3664 | 3689 | ||
| 3665 | ((null (cdr comps)) ;one match | 3690 | ((null (cdr comps)) ;one match |
| 3666 | (concat (if (> (length (ido-name (car comps))) (length name)) | 3691 | (concat (if (> (length (ido-name (car comps))) (length name)) |
| @@ -3771,13 +3796,14 @@ See `read-file-name' for additional parameters." | |||
| 3771 | (ido-read-directory-name prompt dir default-filename mustmatch initial)) | 3796 | (ido-read-directory-name prompt dir default-filename mustmatch initial)) |
| 3772 | ((and (not (memq this-command ido-read-file-name-non-ido)) | 3797 | ((and (not (memq this-command ido-read-file-name-non-ido)) |
| 3773 | (or (null predicate) (eq predicate 'file-exists-p))) | 3798 | (or (null predicate) (eq predicate 'file-exists-p))) |
| 3774 | (let (filename | 3799 | (let* (filename |
| 3775 | ido-saved-vc-hb | 3800 | ido-saved-vc-hb |
| 3776 | (vc-handled-backends (and (boundp 'vc-handled-backends) vc-handled-backends)) | 3801 | (vc-handled-backends (and (boundp 'vc-handled-backends) vc-handled-backends)) |
| 3777 | (ido-current-directory (expand-file-name (or dir default-directory))) | 3802 | (ido-current-directory (ido-expand-directory dir)) |
| 3778 | (ido-work-directory-index -1) | 3803 | (ido-directory-nonreadable (not (file-readable-p ido-current-directory))) |
| 3779 | (ido-work-file-index -1) | 3804 | (ido-work-directory-index -1) |
| 3780 | (ido-find-literal nil)) | 3805 | (ido-work-file-index -1) |
| 3806 | (ido-find-literal nil)) | ||
| 3781 | (setq filename | 3807 | (setq filename |
| 3782 | (ido-read-internal 'file prompt 'ido-file-history default-filename mustmatch initial)) | 3808 | (ido-read-internal 'file prompt 'ido-file-history default-filename mustmatch initial)) |
| 3783 | (if filename | 3809 | (if filename |
| @@ -3790,11 +3816,12 @@ See `read-file-name' for additional parameters." | |||
| 3790 | (defun ido-read-directory-name (prompt &optional dir default-dirname mustmatch initial) | 3816 | (defun ido-read-directory-name (prompt &optional dir default-dirname mustmatch initial) |
| 3791 | "Read directory name, prompting with PROMPT and completing in directory DIR. | 3817 | "Read directory name, prompting with PROMPT and completing in directory DIR. |
| 3792 | See `read-file-name' for additional parameters." | 3818 | See `read-file-name' for additional parameters." |
| 3793 | (let (filename | 3819 | (let* (filename |
| 3794 | ido-saved-vc-hb | 3820 | ido-saved-vc-hb |
| 3795 | (ido-current-directory (expand-file-name (or dir default-directory))) | 3821 | (ido-current-directory (ido-expand-directory dir)) |
| 3796 | (ido-work-directory-index -1) | 3822 | (ido-directory-nonreadable (not (file-readable-p ido-current-directory))) |
| 3797 | (ido-work-file-index -1)) | 3823 | (ido-work-directory-index -1) |
| 3824 | (ido-work-file-index -1)) | ||
| 3798 | (setq filename | 3825 | (setq filename |
| 3799 | (ido-read-internal 'dir prompt 'ido-file-history default-dirname mustmatch initial)) | 3826 | (ido-read-internal 'dir prompt 'ido-file-history default-dirname mustmatch initial)) |
| 3800 | (if filename | 3827 | (if filename |