# HG changeset patch # User Kim F. Storm # Date 1096069728 0 # Node ID 98f763c22ee42b5e758ac042928942894868ac04 # Parent fb4a971fd9caf795672efd863d7faf93332ffe5a (ido-max-directory-size): New defcustom. (ido-decorations): Add "too big" element. (ido-directory-too-big): New dynamic var. (ido-may-cache-directory): Don't cache big directories. (ido-directory-too-big-p): New defun. (ido-set-current-directory): Update ido-directory-too-big. (ido-read-internal): Make empty ido-cur-item if too-big. (ido-buffer-internal): Use ido-read-internal directly instead of ido-read-buffer. (ido-file-internal): Init ido-directory-too-big. (ido-complete): If ido-directory-too-big is set, clear it, and redo completion with full list. (ido-toggle-ignore): If ido-directory-too-big is set, clear it, and show completions. (ido-all-completions): Let bind ido-directory-too-big to nil. (ido-exhibit): Handle ido-directory-too-big. (ido-read-buffer): Handle fallback to read-buffer. Init ido-directory-too-big. (ido-read-file-name, ido-read-directory-name, ido-completing-read): Init ido-directory-too-big. diff -r fb4a971fd9ca -r 98f763c22ee4 lisp/ido.el --- a/lisp/ido.el Fri Sep 24 23:48:24 2004 +0000 +++ b/lisp/ido.el Fri Sep 24 23:48:48 2004 +0000 @@ -666,6 +666,14 @@ :type 'integer :group 'ido) +(defcustom ido-max-directory-size 30000 + "*Maximum size (in bytes) for directories to use ido completion. +If you enter a directory with a size larger than this size, ido will +not provide the normal completion. To show the completions, use C-a." + :type '(choice (const :tag "No limit" nil) + (integer :tag "Size in bytes" 30000)) + :group 'ido) + (defcustom ido-rotate-file-list-default nil "*Non-nil means that `ido' will always rotate file list to get default in front." :type 'boolean @@ -699,9 +707,9 @@ :type '(choice string (const nil)) :group 'ido) -(defcustom ido-decorations '( "{" "}" " | " " | ..." "[" "]" " [No match]" " [Matched]" " [Not readable]") +(defcustom ido-decorations '( "{" "}" " | " " | ..." "[" "]" " [No match]" " [Matched]" " [Not readable]" " [Too big]") "*List of strings used by ido to display the alternatives in the minibuffer. -There are 9 elements in this list: +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), 4th element is the string inserted at the end of a truncated list of prospects, @@ -709,7 +717,8 @@ can be completed using TAB, 7th element is the string displayed when there are a no matches, and 8th element is displayed if there is a single match (and faces are not used). -9th element is displayed when the current directory is non-readable." +9th element is displayed when the current directory is non-readable. +10th element is displayed when directory exceeds `ido-max-directory-size'." :type '(repeat string) :group 'ido) @@ -952,6 +961,9 @@ ;; Remember if current directory is non-readable (so we cannot do completion). (defvar ido-directory-nonreadable) +;; Remember if current directory is 'huge' (so we don't want to do completion). +(defvar ido-directory-too-big) + ;; Keep current item list if non-nil. (defvar ido-keep-item-list) @@ -1082,6 +1094,8 @@ (defun ido-may-cache-directory (&optional dir) (setq dir (or dir ido-current-directory)) (cond + ((ido-directory-too-big-p dir) + nil) ((and (ido-is-root-directory dir) (or ido-enable-tramp-completion (memq system-type '(windows-nt ms-dos)))) @@ -1425,6 +1439,16 @@ (file-directory-p dir) (not (file-readable-p dir))))) +(defun ido-directory-too-big-p (dir) + ;; Return t if dir is a directory, but too big to show + ;; Do not check for non-readable directories via tramp, as this causes a premature + ;; connect on incomplete tramp paths (after entring just method:). + (let ((ido-enable-tramp-completion nil)) + (and (numberp ido-max-directory-size) + (ido-final-slash dir) + (file-directory-p dir) + (> (nth 7 (file-attributes dir)) ido-max-directory-size)))) + (defun ido-set-current-directory (dir &optional subdir no-merge) ;; Set ido's current directory to DIR or DIR/SUBDIR (setq dir (ido-final-slash dir t)) @@ -1439,6 +1463,8 @@ (if (get-buffer ido-completion-buffer) (kill-buffer ido-completion-buffer)) (setq ido-directory-nonreadable (ido-nonreadable-directory-p dir)) + (setq ido-directory-too-big (and (not ido-directory-nonreadable) + (ido-directory-too-big-p dir))) t)) (defun ido-set-current-home (&optional dir) @@ -1623,10 +1649,14 @@ ido-rescan nil)) ((eq ido-cur-item 'file) (setq ido-ignored-list nil - ido-cur-list (ido-make-file-list ido-default-item))) + ido-cur-list (and (not ido-directory-nonreadable) + (not ido-directory-too-big) + (ido-make-file-list ido-default-item)))) ((eq ido-cur-item 'dir) (setq ido-ignored-list nil - ido-cur-list (ido-make-dir-list ido-default-item))) + ido-cur-list (and (not ido-directory-nonreadable) + (not ido-directory-too-big) + (ido-make-dir-list ido-default-item)))) ((eq ido-cur-item 'buffer) (setq ido-ignored-list nil ido-cur-list (ido-make-buffer-list ido-default-item))) @@ -1802,7 +1832,10 @@ (if (not ido-mode) (call-interactively (or fallback 'switch-to-buffer)) (let* ((ido-context-switch-command switch-cmd) - (buf (ido-read-buffer (or prompt "Buffer: ") default nil initial))) + (ido-current-directory nil) + (ido-directory-nonreadable nil) + (ido-directory-too-big nil) + (buf (ido-read-internal 'buffer (or prompt "Buffer: ") 'ido-buffer-history default nil initial))) ;; Choose the buffer name: either the text typed in, or the head ;; of the list of matches @@ -1845,19 +1878,6 @@ (set-buffer-major-mode buf)) (ido-visit-buffer buf method t)))))) -;;;###autoload -(defun ido-read-buffer (prompt &optional default require-match initial) - "Replacement for the built-in `read-buffer'. -Return the name of a buffer selected. -PROMPT is the prompt to give to the user. DEFAULT if given is the default -buffer to be selected, which will go to the front of the list. -If REQUIRE-MATCH is non-nil, an existing-buffer must be selected. -If INITIAL is non-nil, it specifies the initial input string." - (let ((ido-current-directory nil) - (ido-directory-nonreadable nil) - (ido-context-switch-command (if (boundp 'ido-context-switch-command) ido-context-switch-command 'ignore))) - (ido-read-internal 'buffer prompt 'ido-buffer-history default require-match initial))) - (defun ido-record-work-directory (&optional dir) (when (and (numberp ido-max-work-directory-list) (> ido-max-work-directory-list 0)) (if (and (setq dir (or dir ido-current-directory)) (> (length dir) 0)) @@ -1905,6 +1925,8 @@ (setq item 'file)) (let* ((ido-current-directory (ido-expand-directory default)) (ido-directory-nonreadable (ido-nonreadable-directory-p ido-current-directory)) + (ido-directory-too-big (and (not ido-directory-nonreadable) + (ido-directory-too-big-p ido-current-directory))) (ido-context-switch-command switch-cmd) filename) @@ -2079,6 +2101,12 @@ (setq ido-exit 'refresh) (exit-minibuffer)))) + (ido-directory-too-big + (setq ido-directory-too-big nil) + (setq ido-text-init ido-text) + (setq ido-exit 'refresh) + (exit-minibuffer)) + ((not ido-matches) (when ido-completion-buffer (call-interactively (setq this-command ido-cannot-complete-command)))) @@ -2182,7 +2210,9 @@ (defun ido-toggle-ignore () "Toggle ignoring files specified with `ido-ignore-files'." (interactive) - (setq ido-process-ignore-lists (not ido-process-ignore-lists)) + (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)) @@ -2324,6 +2354,7 @@ (not (equal dir ido-current-directory)) (file-directory-p dir) (or (not must-match) + ;; TODO. check for nonreadable and too-big. (ido-set-matches1 (if (eq ido-cur-item 'file) (ido-make-file-list1 dir) @@ -2581,7 +2612,8 @@ (defun ido-all-completions () ;; Return unsorted list of all competions. - (let ((ido-process-ignore-lists nil)) + (let ((ido-process-ignore-lists nil) + (ido-directory-too-big nil)) (cond ((eq ido-cur-item 'file) (ido-make-file-list1 ido-current-directory)) @@ -2700,6 +2732,7 @@ (or ido-merge-ftp-work-directories (not (ido-is-ftp-directory dir))) (file-directory-p dir) + ;; TODO. check for nonreadable and too-big. (setq fl (if (eq ido-cur-item 'file) (ido-make-file-list1 dir t) (ido-make-dir-list1 dir t)))) @@ -2780,6 +2813,8 @@ (defun ido-file-name-all-completions1 (dir) (cond ((ido-nonreadable-directory-p dir) '()) + ;; do not check (ido-directory-too-big-p dir) here. + ;; Caller must have done that if necessary. ((and ido-enable-tramp-completion (string-match "\\`/\\([^/:]+:\\([^/:@]+@\\)?\\)\\'" dir)) @@ -3616,7 +3651,7 @@ (expand-file-name "/" ido-current-directory) "/")) (setq refresh t)) - ((and ido-directory-nonreadable + ((and (or ido-directory-nonreadable ido-directory-too-big) (file-directory-p (concat ido-current-directory (file-name-directory contents)))) (ido-set-current-directory (concat ido-current-directory (file-name-directory contents))) @@ -3678,6 +3713,7 @@ (when (and (not ido-matches) (not ido-directory-nonreadable) + (not ido-directory-too-big) ;; ido-rescan ? ido-process-ignore-lists ido-ignored-list) @@ -3701,7 +3737,8 @@ (not (ido-is-root-directory)) (> (length contents) 1) (not (string-match "[$]" contents)) - (not ido-directory-nonreadable)) + (not ido-directory-nonreadable) + (not ido-directory-too-big)) (ido-trace "merge?") (if ido-use-merged-list (ido-undo-merge-work-directory contents nil) @@ -3766,6 +3803,8 @@ (cond (ido-directory-nonreadable (or (nth 8 ido-decorations) " [Not readable]")) + (ido-directory-too-big + (or (nth 9 ido-decorations) " [Too big]")) (ido-report-no-match (nth 6 ido-decorations)) ;; [No match] (t ""))) @@ -3872,8 +3911,26 @@ (put 'dired-do-rename 'ido 'ignore) ;;;###autoload +(defun ido-read-buffer (prompt &optional default require-match) + "Ido replacement for the built-in `read-buffer'. +Return the name of a buffer selected. +PROMPT is the prompt to give to the user. DEFAULT if given is the default +buffer to be selected, which will go to the front of the list. +If REQUIRE-MATCH is non-nil, an existing-buffer must be selected." + (let* ((ido-current-directory nil) + (ido-directory-nonreadable nil) + (ido-directory-too-big nil) + (ido-context-switch-command 'ignore) + (buf (ido-read-internal 'buffer prompt 'ido-buffer-history default require-match))) + (if (eq ido-exit 'fallback) + (let ((read-buffer-function nil)) + (read-buffer prompt default require-match)) + buf))) + +;;;###autoload (defun ido-read-file-name (prompt &optional dir default-filename mustmatch initial predicate) - "Read file name, prompting with PROMPT and completing in directory DIR. + "Ido replacement for the built-in `read-file-name'. +Read file name, prompting with PROMPT and completing in directory DIR. See `read-file-name' for additional parameters." (let (filename) (cond @@ -3890,6 +3947,8 @@ (vc-handled-backends (and (boundp 'vc-handled-backends) vc-handled-backends)) (ido-current-directory (ido-expand-directory dir)) (ido-directory-nonreadable (not (file-readable-p ido-current-directory))) + (ido-directory-too-big (and (not ido-directory-nonreadable) + (ido-directory-too-big-p ido-current-directory))) (ido-work-directory-index -1) (ido-work-file-index -1) (ido-find-literal nil)) @@ -3911,13 +3970,16 @@ ;;;###autoload (defun ido-read-directory-name (prompt &optional dir default-dirname mustmatch initial) - "Read directory name, prompting with PROMPT and completing in directory DIR. -See `read-file-name' for additional parameters." + "Ido replacement for the built-in `read-directory-name'. +Read directory name, prompting with PROMPT and completing in directory DIR. +See `read-directory-name' for additional parameters." (let* (filename (ido-context-switch-command 'ignore) ido-saved-vc-hb (ido-current-directory (ido-expand-directory dir)) (ido-directory-nonreadable (not (file-readable-p ido-current-directory))) + (ido-directory-too-big (and (not ido-directory-nonreadable) + (ido-directory-too-big-p ido-current-directory))) (ido-work-directory-index -1) (ido-work-file-index -1)) (setq filename @@ -3929,7 +3991,8 @@ ;;;###autoload (defun ido-completing-read (prompt choices &optional predicate require-match initial-input hist def) - "Read a string in the minibuffer with ido-style completion. + "Ido replacement for the built-in `completing-read'. +Read a string in the minibuffer with ido-style completion. PROMPT is a string to prompt with; normally it ends in a colon and a space. CHOICES is a list of strings which are the possible completions. PREDICATE is currently ignored; it is included to be compatible @@ -3944,6 +4007,7 @@ DEF, if non-nil, is the default value." (let ((ido-current-directory nil) (ido-directory-nonreadable nil) + (ido-directory-too-big nil) (ido-context-switch-command 'ignore) (ido-choice-list choices)) (ido-read-internal 'list prompt hist def require-match initial-input)))