From db9f395b9291b23049bb965fc849fd67e43ad944 Mon Sep 17 00:00:00 2001 From: "Kim F. Storm" Date: Wed, 22 Sep 2004 22:49:07 +0000 Subject: [PATCH] (ido-choice-list): New dynamic var for `list' context. (ido-context-switch-command): New dynamic var. (ido-define-mode-map): Generalize switch between file/buffer contexts. (ido-read-internal): Handle new `list' context. Handle insert-buffer and insert-file ido-exit values. (ido-buffer-internal): New arg switch-cmd. Use it to setup ido-context-switch-command. Handle insert-file ido-exit value. (ido-read-buffer): Set ido-context-switch-command to 'ignore unless it is already bound by caller. (ido-file-internal): New arg switch-cmd. Use it to setup ido-context-switch-command. Handle insert-buffer ido-exit value. (ido-enter-insert-buffer, ido-enter-insert-file): New commands used for context switching. (ido-all-completions): Handle new `list' context. (ido-make-choice-list): Return choices for `list' context. (ido-find-file-in-dir, ido-display-file, ido-write-file) (ido-display-buffer, ido-kill-buffer): Disable context switching. (ido-insert-buffer, ido-insert-file): Setup context switching. (ido-exhibit): Handle `list' context. (ido-read-file-name): Disable context switching. Handle fallback. (ido-read-directory-name): Disable context switching. (ido-completing-read): New defun like completing-read. Setup and use new `list' context. --- lisp/ido.el | 166 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 122 insertions(+), 44 deletions(-) diff --git a/lisp/ido.el b/lisp/ido.el index b82338ef85d..7f149af1e87 100644 --- a/lisp/ido.el +++ b/lisp/ido.el @@ -933,7 +933,7 @@ it doesn't interfere with other minibuffer usage.") ;;; Variables with dynamic bindings. ;;; Declared here to keep the byte compiler quiet. -;; Stores the current ido item type ('file, 'dir or 'buffer). +;; Stores the current ido item type ('file, 'dir, 'buffer, or 'list). (defvar ido-cur-item) ;; Stores the current list of items that will be searched through. @@ -942,6 +942,9 @@ it doesn't interfere with other minibuffer usage.") ;; at the end of the list. Created by `ido-make-item-list'. (defvar ido-cur-list) +;; Stores the choice list for ido-completing-read +(defvar ido-choice-list) + ;; Stores the list of items which are ignored when building ;; `ido-cur-list'. It is in no specific order. (defvar ido-ignored-list) @@ -992,6 +995,8 @@ it doesn't interfere with other minibuffer usage.") ;; Stores temporary state of literal find file. (defvar ido-find-literal) +;; Set to 'ignore to inhibit switching between find-file/switch-buffer. +(defvar ido-context-switch-command) ;;; FUNCTIONS @@ -1346,8 +1351,8 @@ This function also adds a hook to the minibuffer." (define-key map "?" 'ido-completion-help) (when (memq ido-cur-item '(file dir)) - (define-key map "\C-b" 'ido-enter-switch-buffer) - (define-key map "\C-d" 'ido-enter-dired) + (define-key map "\C-b" (or ido-context-switch-command 'ido-enter-switch-buffer)) + (define-key map "\C-d" (or (and ido-context-switch-command 'ignore) 'ido-enter-dired)) (define-key map "\C-f" 'ido-fallback-command) (define-key map [down] 'ido-next-match-dir) (define-key map [up] 'ido-prev-match-dir) @@ -1378,8 +1383,8 @@ This function also adds a hook to the minibuffer." ) (when (eq ido-cur-item 'buffer) + (define-key map "\C-f" (or ido-context-switch-command 'ido-enter-find-file)) (define-key map "\C-b" 'ido-fallback-command) - (define-key map "\C-f" 'ido-enter-find-file) (define-key map "\C-k" 'ido-kill-buffer-at-head) ) @@ -1625,6 +1630,9 @@ If INITIAL is non-nil, it specifies the initial input string." ((eq ido-cur-item 'buffer) (setq ido-ignored-list nil ido-cur-list (ido-make-buffer-list ido-default-item))) + ((eq ido-cur-item 'list) + (setq ido-ignored-list nil + ido-cur-list (ido-make-choice-list ido-default-item))) (t nil)) (setq ido-rotate-temp nil) @@ -1709,7 +1717,7 @@ If INITIAL is non-nil, it specifies the initial input string." ((eq ido-exit 'keep) (setq ido-keep-item-list t)) - ((memq ido-exit '(dired fallback findfile findbuffer)) + ((memq ido-exit '(dired fallback find-file switch-to-buffer insert-buffer insert-file)) (setq done t)) ((eq ido-exit 'updir) @@ -1789,19 +1797,23 @@ If INITIAL is non-nil, it specifies the initial input string." (exit-minibuffer)) ;;; MAIN FUNCTIONS -(defun ido-buffer-internal (method &optional fallback prompt default initial) +(defun ido-buffer-internal (method &optional fallback prompt default initial switch-cmd) ;; Internal function for ido-switch-buffer and friends (if (not ido-mode) (call-interactively (or fallback 'switch-to-buffer)) - (let ((buf (ido-read-buffer (or prompt "Buffer: ") default nil initial))) + (let* ((ido-context-switch-command switch-cmd) + (buf (ido-read-buffer (or prompt "Buffer: ") default nil initial))) ;; Choose the buffer name: either the text typed in, or the head ;; of the list of matches (cond - ((eq ido-exit 'findfile) + ((eq ido-exit 'find-file) (ido-file-internal ido-default-file-method nil nil nil nil ido-text)) + ((eq ido-exit 'insert-file) + (ido-file-internal 'insert 'insert-file nil "Insert file: " nil ido-text 'ido-enter-insert-buffer)) + ((eq ido-exit 'fallback) (let ((read-buffer-function nil)) (call-interactively (or fallback 'switch-to-buffer)))) @@ -1842,7 +1854,8 @@ 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-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) @@ -1886,12 +1899,13 @@ If INITIAL is non-nil, it specifies the initial input string." ;; Add final slash to result in case it was missing from DEFAULT-DIRECTORY. (ido-final-slash (expand-file-name (or dir default-directory)) t)) -(defun ido-file-internal (method &optional fallback default prompt item initial) +(defun ido-file-internal (method &optional fallback default prompt item initial switch-cmd) ;; Internal function for ido-find-file and friends (unless item (setq item 'file)) (let* ((ido-current-directory (ido-expand-directory default)) (ido-directory-nonreadable (ido-nonreadable-directory-p ido-current-directory)) + (ido-context-switch-command switch-cmd) filename) (cond @@ -1943,9 +1957,12 @@ If INITIAL is non-nil, it specifies the initial input string." (read-file-name-function nil)) (call-interactively (or fallback 'find-file)))) - ((eq ido-exit 'findbuffer) + ((eq ido-exit 'switch-to-buffer) (ido-buffer-internal ido-default-buffer-method nil nil nil ido-text)) + ((eq ido-exit 'insert-buffer) + (ido-buffer-internal 'insert 'insert-buffer "Insert buffer: " nil ido-text 'ido-enter-insert-file)) + ((eq ido-exit 'dired) (dired (concat ido-current-directory (or ido-text "")))) @@ -2227,13 +2244,13 @@ If no buffer or file exactly matching the prompt exists, maybe create a new one. (defun ido-enter-find-file () "Drop into find-file from buffer switching." (interactive) - (setq ido-exit 'findfile) + (setq ido-exit 'find-file) (exit-minibuffer)) (defun ido-enter-switch-buffer () "Drop into ido-switch-buffer from file switching." (interactive) - (setq ido-exit 'findbuffer) + (setq ido-exit 'switch-to-buffer) (exit-minibuffer)) (defun ido-enter-dired () @@ -2242,6 +2259,18 @@ If no buffer or file exactly matching the prompt exists, maybe create a new one. (setq ido-exit 'dired) (exit-minibuffer)) +(defun ido-enter-insert-buffer () + "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." + (interactive) + (setq ido-exit 'insert-file) + (exit-minibuffer)) + (defun ido-up-directory (&optional clear) "Go up one directory level." @@ -2560,6 +2589,8 @@ for first matching file." (ido-make-dir-list1 ido-current-directory)) ((eq ido-cur-item 'buffer) (ido-make-buffer-list1)) + ((eq ido-cur-item 'list) + ido-choice-list) (t nil)))) @@ -2722,6 +2753,20 @@ for first matching file." (run-hooks 'ido-make-buffer-list-hook) ido-temp-list)) +(defun ido-make-choice-list (default) + ;; Return the current list of choices. + ;; If DEFAULT is non-nil, and corresponds to an element of choices, + ;; it is put to the start of the list. + (let ((ido-temp-list ido-choice-list)) + (if default + (progn + (setq ido-temp-list + (delete default ido-temp-list)) + (setq ido-temp-list + (cons default ido-temp-list)))) + ; (run-hooks 'ido-make-choice-list-hook) + ido-temp-list)) + (defun ido-to-end (items) ;; Move the elements from ITEMS to the end of `ido-temp-list' (mapcar @@ -3277,7 +3322,7 @@ For details of keybindings, do `\\[describe-function] ido'." The buffer name is selected interactively by typing a substring. For details of keybindings, do `\\[describe-function] ido'." (interactive) - (ido-buffer-internal 'display 'display-buffer)) + (ido-buffer-internal 'display 'display-buffer nil nil nil 'ignore)) ;;;###autoload (defun ido-kill-buffer () @@ -3285,7 +3330,7 @@ For details of keybindings, do `\\[describe-function] ido'." The buffer name is selected interactively by typing a substring. For details of keybindings, do `\\[describe-function] ido'." (interactive) - (ido-buffer-internal 'kill 'kill-buffer "Kill buffer: " (buffer-name (current-buffer)))) + (ido-buffer-internal 'kill 'kill-buffer "Kill buffer: " (buffer-name (current-buffer)) nil 'ignore)) ;;;###autoload (defun ido-insert-buffer () @@ -3293,7 +3338,7 @@ For details of keybindings, do `\\[describe-function] ido'." The buffer name is selected interactively by typing a substring. For details of keybindings, do `\\[describe-function] ido'." (interactive) - (ido-buffer-internal 'insert 'insert-buffer "Insert buffer: ")) + (ido-buffer-internal 'insert 'insert-buffer "Insert buffer: " nil nil 'ido-enter-insert-file)) ;;;###autoload (defun ido-switch-buffer-other-frame () @@ -3311,7 +3356,7 @@ For details of keybindings, do `\\[describe-function] ido'." (interactive "DDir: ") (if (not (equal (substring dir -1) "/")) (setq dir (concat dir "/"))) - (ido-file-internal ido-default-file-method nil dir)) + (ido-file-internal ido-default-file-method nil dir nil nil nil 'ignore)) ;;;###autoload (defun ido-find-file () @@ -3404,7 +3449,7 @@ For details of keybindings, do `\\[describe-function] ido-find-file'." The file name is selected interactively by typing a substring. For details of keybindings, do `\\[describe-function] ido-find-file'." (interactive) - (ido-file-internal 'display)) + (ido-file-internal 'display nil nil nil nil nil 'ignore)) ;;;###autoload (defun ido-find-file-other-frame () @@ -3426,7 +3471,7 @@ For details of keybindings, do `\\[describe-function] ido-find-file'." (ido-report-no-match nil) (ido-confirm-unique-completion t) (ido-auto-merge-work-directories-length -1)) - (ido-file-internal 'write 'write-file nil "Write file: "))) + (ido-file-internal 'write 'write-file nil "Write file: " nil nil 'ignore))) ;;;###autoload (defun ido-insert-file () @@ -3434,7 +3479,7 @@ For details of keybindings, do `\\[describe-function] ido-find-file'." The file name is selected interactively by typing a substring. For details of keybindings, do `\\[describe-function] ido-find-file'." (interactive) - (ido-file-internal 'insert 'insert-file nil "Insert file: ")) + (ido-file-internal 'insert 'insert-file nil "Insert file: " nil nil 'ido-enter-insert-buffer)) ;;;###autoload (defun ido-dired () @@ -3515,7 +3560,7 @@ For details of keybindings, do `\\[describe-function] ido-find-file'." ;; Handle explicit directory changes (cond - ((eq ido-cur-item 'buffer) + ((memq ido-cur-item '(buffer list)) ) ((= (length contents) 0) @@ -3830,35 +3875,46 @@ For details of keybindings, do `\\[describe-function] ido-find-file'." (defun ido-read-file-name (prompt &optional dir default-filename mustmatch initial predicate) "Read file name, prompting with PROMPT and completing in directory DIR. See `read-file-name' for additional parameters." - (cond - ((or (eq predicate 'file-directory-p) - (eq (get this-command 'ido) 'dir) - (memq this-command ido-read-file-name-as-directory-commands)) - (ido-read-directory-name prompt dir default-filename mustmatch initial)) - ((and (not (eq (get this-command 'ido) 'ignore)) - (not (memq this-command ido-read-file-name-non-ido)) - (or (null predicate) (eq predicate 'file-exists-p))) - (let* (filename - ido-saved-vc-hb - (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-work-directory-index -1) - (ido-work-file-index -1) - (ido-find-literal nil)) - (setq filename - (ido-read-internal 'file prompt 'ido-file-history default-filename mustmatch initial)) - (if filename - (concat ido-current-directory filename)))) - (t - (let ((read-file-name-function nil)) - (read-file-name prompt dir default-filename mustmatch initial predicate))))) + (let (filename) + (cond + ((or (eq predicate 'file-directory-p) + (eq (get this-command 'ido) 'dir) + (memq this-command ido-read-file-name-as-directory-commands)) + (setq filename + (ido-read-directory-name prompt dir default-filename mustmatch initial))) + ((and (not (eq (get this-command 'ido) 'ignore)) + (not (memq this-command ido-read-file-name-non-ido)) + (or (null predicate) (eq predicate 'file-exists-p))) + (let* (ido-saved-vc-hb + (ido-context-switch-command 'ignore) + (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-work-directory-index -1) + (ido-work-file-index -1) + (ido-find-literal nil)) + (setq ido-exit nil) + (setq filename + (ido-read-internal 'file prompt 'ido-file-history default-filename mustmatch initial)) + (cond + ((eq ido-exit 'fallback) + (setq filename 'fallback)) + (filename + (setq filename + (concat ido-current-directory filename)))))) + (t + (setq filename 'fallback))) + (if (eq filename 'fallback) + (let ((read-file-name-function nil)) + (read-file-name prompt dir default-filename mustmatch initial predicate)) + filename))) ;;;###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." (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))) @@ -3871,5 +3927,27 @@ See `read-file-name' for additional parameters." ido-current-directory (concat ido-current-directory filename))))) +;;;###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. +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 + with `completing-read'. +If REQUIRE-MATCH is non-nil, the user is not allowed to exit unless + the input is (or completes to) an element of CHOICES or is null. + If the input is null, `ido-completing-read' returns DEF, or an empty + string if DEF is nil, regardless of the value of REQUIRE-MATCH. +If INITIAL-INPUT is non-nil, insert it in the minibuffer initially, + with point positioned at the end. +HIST, if non-nil, specifies a history list. +DEF, if non-nil, is the default value." + (let ((ido-current-directory nil) + (ido-directory-nonreadable nil) + (ido-context-switch-command 'ignore) + (ido-choice-list choices)) + (ido-read-internal 'list prompt hist def require-match initial-input))) + + ;;; arch-tag: b63a3500-1735-41bd-8a01-05373f0864da ;;; ido.el ends here -- 2.39.2