;;; ido.el --- interactively do things with buffers and files.
-;; Copyright (C) 1996-2004 Free Software Foundation, Inc.
+;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+;; 2004, 2005 Free Software Foundation, Inc.
;; Author: Kim F. Storm <storm@cua.dk>
;; Based on: iswitchb by Stephen Eglen <stephen@cns.ed.ac.uk>
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
;;; Acknowledgements
;; so I invented a common "ido-" namespace for the merged packages.
;;
;; This version is based on ido.el version 1.57 released on
-;; gnu.emacs.sources adapted for emacs 21.5 to use command remapping
+;; gnu.emacs.sources adapted for emacs 22.1 to use command remapping
;; and optionally hooking the read-buffer and read-file-name functions.
;;
;; Prefix matching was added by Klaus Berndl <klaus.berndl@sdm.de> based on
;; The list in {...} are the matching buffers, most recent first
;; (buffers visible in the current frame are put at the end of the
;; list by default). At any time I can select the item at the head of
-;; the list by pressing RET. I can also bring the put the first
-;; element at the end of the list by pressing C-s or [right], or put
-;; the last element at the head of the list by pressing C-r or [left].
+;; the list by pressing RET. I can also put the first element at the
+;; end of the list by pressing C-s or [right], or bring the last
+;; element to the head of the list by pressing C-r or [left].
;;
;; The item in [...] indicates what can be added to my input by
;; pressing TAB. In this case, I will get "3" added to my input.
;; Example:
;;
;; If you have again two Buffers "123456" and "123" then hitting "2" does
-;; not match because "2" is not a PREFIX in any of the buffer-names. This
-;; is the only difference between the substring and prefix matching.
+;; not match because "2" is not a PREFIX in any of the buffer-names.
;; Flexible matching
;; -----------------
;;
;; There is limited provision for regexp matching within ido,
;; enabled through `ido-enable-regexp' (toggle with C-t).
-;; This allows you to type `c$' for example and see all file names
-;; ending in `c'. This facility is quite limited though in two
-;; respects. First, you can't currently type in expressions like
-;; `[0-9]' directly -- you have to type them in when ido-enable-regexp
-;; is nil and then toggle on the regexp functionality. Likewise,
-;; don't enter an expression containing `\' in regexp mode. If you
-;; try, ido gets confused, so just hit C-g and try again. Secondly,
-;; no completion mechanism is currently offered with regexp searching.
+;; This allows you to type `[ch]$' for example and see all file names
+;; ending in `c' or `h'.
+;;
+;; Note: ido-style completion is inhibited when you enable regexp matching.
;; Customization
;;
;; Customize the `ido' group to change the `ido' functionality.
;;
-;; To modify the keybindings, use the hook provided. For example:
-;;(add-hook 'ido-define-mode-map-hook 'ido-my-keys)
+;; To modify the keybindings, use the ido-setup-hook. For example:
+;;(add-hook 'ido-setup-hook 'ido-my-keys)
;;
;;(defun ido-my-keys ()
;; "Add my keybindings for ido."
;; ------------
;; The highlighting of matching items is controlled via ido-use-faces.
-;; The faces used are ido-first-match-face, ido-only-match-face and
-;; ido-subdir-face.
+;; The faces used are ido-first-match, ido-only-match and
+;; ido-subdir.
;; Colouring of the matching item was suggested by
;; Carsten Dominik (dominik@strw.leidenuniv.nl).
"Switch between files using substrings."
:group 'extensions
:group 'convenience
+ :version "22.1"
:link '(emacs-commentary-link :tag "Commentary" "ido.el")
:link '(emacs-library-link :tag "Lisp File" "ido.el"))
;;;###autoload
(defcustom ido-mode nil
"Determines for which functional group \(buffer and files) ido behavior
-should be enabled. The following values are possible:
+should be enabled. The following values are possible:
- `buffer': Turn only on ido buffer behavior \(switching, killing,
displaying...)
- `file': Turn only on ido file behavior \(finding, writing, inserting...)
:require 'ido
:link '(emacs-commentary-link "ido.el")
:set-after '(ido-save-directory-list-file)
- :version "21.4"
:type '(choice (const :tag "Turn on only buffer" buffer)
(const :tag "Turn on only file" file)
(const :tag "Turn on both buffer and file" both)
Setting this variable directly does not work. Use `customize' or
call the function `ido-everywhere'."
:set #'(lambda (symbol value)
- (ido-everywhere value))
+ (ido-everywhere (if value 1 -1)))
:initialize 'custom-initialize-default
:type 'boolean
:group 'ido)
:type 'boolean
:group 'ido)
+(defcustom ido-file-extensions-order nil
+ "*List of file extensions specifying preferred order of file selections.
+Each element is either a string with `.' as the first char, an empty
+string matching files without extension, or t which is the default order
+for files with an unlisted file extension."
+ :type '(repeat (choice string
+ (const :tag "Default order" t)))
+ :group 'ido)
+
(defcustom ido-ignore-directories
'("\\`CVS/" "\\`\\.\\./" "\\`\\./")
"*List of regexps or functions matching sub-directory names to ignore."
`otherframe' Show new file in another frame
`maybe-frame' If a file is visible in another frame, prompt to ask if you
you want to see the file in the same window of the current
- frame or in the other frame.
+ frame or in the other frame
`always-frame' If a file is visible in another frame, raise that
- frame. Otherwise, visit the file in the same window."
+ frame; otherwise, visit the file in the same window"
:type '(choice (const samewindow)
(const otherwindow)
(const display)
(defcustom ido-default-buffer-method 'always-frame
"*How to switch to new buffer when using `ido-switch-buffer'.
-See ido-default-file-method for details."
+See `ido-default-file-method' for details."
:type '(choice (const samewindow)
(const otherwindow)
(const display)
(defcustom ido-max-prospects 12
"*Non-zero means that the prospect list will be limited to than number of items.
For a long list of prospects, building the full list for the minibuffer can take a
-non-negletable amount of time; setting this variable reduces that time."
+non-negligible amount of time; setting this variable reduces that time."
:type 'integer
:group 'ido)
(defcustom ido-use-filename-at-point nil
"*Non-nil means that ido shall look for a filename at point.
+May use `ffap-guesser' to guess whether text at point is a filename.
If found, use that as the starting point for filename selection."
- :type 'boolean
+ :type '(choice
+ (const :tag "Disabled" nil)
+ (const :tag "Guess filename" guess)
+ (other :tag "Use literal filename" t))
:group 'ido)
(defcustom ido-slow-ftp-hosts nil
"*List of slow ftp hosts where ido prompting should not be used.
If an ftp host is on this list, ido automatically switches to the non-ido
-equivalent function, e.g. find-file rather than ido-find-file."
+equivalent function, e.g. `find-file' rather than `ido-find-file'."
:type '(repeat string)
:group 'ido)
:type 'boolean
:group 'ido)
-(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."
+(defcustom ido-enter-matching-directory 'only
+ "*Additional methods to enter sub-directory of first/only matching item.
+If value is 'first, enter first matching sub-directory when typing a slash.
+If value is 'only, typing a slash only enters the sub-directory if it is
+the only matching item.
+If value is t, automatically enter a sub-directory when it is the only
+matching item, even without typing a slash."
:type '(choice (const :tag "Never" nil)
- (const :tag "When typing /" slash)
- (other :tag "Always" t))
+ (const :tag "Slash enters first directory" first)
+ (const :tag "Slash enters first and only directory" only)
+ (other :tag "Always enter unique directory" t))
:group 'ido)
(defcustom ido-create-new-buffer 'prompt
(const never))
:group 'ido)
-(defcustom ido-define-mode-map-hook nil
- "*Hook to define keys in `ido-mode-map' for extra keybindings."
+(defcustom ido-setup-hook nil
+ "*Hook run after the ido variables and keymap have been setup.
+The dynamic variable `ido-cur-item' contains the current type of item that
+is read by ido, possible values are file, dir, buffer, and list.
+Additional keys can be defined in `ido-mode-map'."
:type 'hook
:group 'ido)
4th element is the string inserted at the end of a truncated list of prospects,
5th and 6th elements are used as brackets around the common match string which
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.
+7th element is the string displayed when there are 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,
10th element is displayed when directory exceeds `ido-max-directory-size'."
:type '(repeat string)
:group 'ido)
:type 'boolean
:group 'ido)
-(defface ido-first-match-face '((t (:bold t)))
+(defface ido-first-match '((t (:bold t)))
"*Font used by ido for highlighting first match."
:group 'ido)
-(defface ido-only-match-face '((((class color))
+(defface ido-only-match '((((class color))
(:foreground "ForestGreen"))
(t (:italic t)))
"*Font used by ido for highlighting only match."
:group 'ido)
-(defface ido-subdir-face '((((class color))
+(defface ido-subdir '((((min-colors 88) (class color))
+ (:foreground "red1"))
+ (((class color))
(:foreground "red"))
(t (:underline t)))
"*Font used by ido for highlighting subdirs in the alternatives."
:group 'ido)
-(defface ido-indicator-face '((((class color))
+(defface ido-indicator '((((min-colors 88) (class color))
+ (:foreground "yellow1"
+ :background "red1"
+ :width condensed))
+ (((class color))
(:foreground "yellow"
:background "red"
:width condensed))
"*Font used by ido for highlighting its indicators."
:group 'ido)
+(defface ido-incomplete-regexp
+ '((t
+ (:inherit font-lock-warning-face)))
+ "Ido face for indicating incomplete regexps."
+ :group 'ido)
+
(defcustom ido-make-file-list-hook nil
"*List of functions to run when the list of matching files is created.
Each function on the list may modify the dynamically bound variable
(defcustom ido-read-file-name-as-directory-commands '()
"List of commands which uses read-file-name to read a directory name.
When `ido-everywhere' is non-nil, the commands in this list will read
-the directory using ido-read-directory-name."
+the directory using `ido-read-directory-name'."
:type '(repeat symbol)
:group 'ido)
(defcustom ido-read-file-name-non-ido '()
"List of commands which shall not read file names the ido way.
When `ido-everywhere' is non-nil, the commands in this list will read
-the file name using normal read-file-name style."
+the file name using normal `read-file-name' style."
:type '(repeat symbol)
:group 'ido)
+(defcustom ido-before-fallback-functions '()
+ "List of functions to call before calling a fallback command.
+The fallback command is passed as an argument to the functions."
+ :type 'hook
+ :group 'ido)
+
;;; Internal Variables
;; Persistent variables
(defvar ido-work-directory-list nil
"List of actual working directory names.
The current directory is inserted at the front of this list whenever a
-file is opened with ido-find-file and family.")
+file is opened with `ido-find-file' and family.")
(defvar ido-work-file-list nil
"List of actual work file names.
(defvar ido-ignore-item-temp-list nil
"List of items to ignore in current ido invocation.
-Intended to be let-bound by functions which calls ido repeatedly.
+Intended to be let-bound by functions which call ido repeatedly.
Should never be set permanently.")
;; Temporary storage
(defvar ido-text-init nil
"The initial string for the users string it is typed in.")
+(defvar ido-input-stack nil
+ "Stores the users strings when user hits M-b/M-f.")
+
(defvar ido-matches nil
"List of files currently matching `ido-text'.")
selected.")
(defvar ido-current-directory nil
- "Current directory for ido-find-file.")
+ "Current directory for `ido-find-file'.")
(defvar ido-auto-merge-timer nil
"Delay timer for auto merge.")
Is set by ido functions to the current minibuffer-depth, so that
it doesn't interfere with other minibuffer usage.")
+(defvar ido-incomplete-regexp nil
+ "Non-nil if an incomplete regexp is entered.")
;;; Variables with dynamic bindings.
;;; Declared here to keep the byte compiler quiet.
(add-hook 'kill-emacs-hook 'ido-kill-emacs-hook)
- (unless ido-minor-mode-map-entry
+ (if ido-minor-mode-map-entry
+ (setcdr ido-minor-mode-map-entry (make-sparse-keymap))
(setq ido-minor-mode-map-entry (cons 'ido-mode (make-sparse-keymap)))
(add-to-list 'minor-mode-map-alist ido-minor-mode-map-entry))
(define-key map [remap display-buffer] 'ido-display-buffer)))))
(defun ido-everywhere (arg)
- "Enable ido everywhere file and directory names are read."
+ "Toggle using ido speed-ups everywhere file and directory names are read.
+With ARG, turn ido speed-up on if arg is positive, off otherwise."
(interactive "P")
(setq ido-everywhere (if arg
(> (prefix-numeric-value arg) 0)
(not ido-everywhere)))
- (setq read-file-name-function
- (and ido-everywhere (memq ido-mode '(both file))
- 'ido-read-file-name))
- (setq read-buffer-function
- (and ido-everywhere (memq ido-mode '(both buffer))
- 'ido-read-buffer)))
+ (when (get 'ido-everywhere 'file)
+ (setq read-file-name-function (car (get 'ido-everywhere 'file)))
+ (put 'ido-everywhere 'file nil))
+ (when (get 'ido-everywhere 'buffer)
+ (setq read-buffer-function (car (get 'ido-everywhere 'buffer)))
+ (put 'ido-everywhere 'buffer nil))
+ (when ido-everywhere
+ (when (memq ido-mode '(both file))
+ (put 'ido-everywhere 'file (cons read-file-name-function nil))
+ (setq read-file-name-function 'ido-read-file-name))
+ (when (memq ido-mode '(both buffer))
+ (put 'ido-everywhere 'buffer (cons read-buffer-function nil))
+ (setq read-buffer-function 'ido-read-buffer))))
;;; IDO KEYMAP
(define-key map "\C-s" 'ido-next-match)
(define-key map "\C-t" 'ido-toggle-regexp)
(define-key map "\C-z" 'ido-undo-merge-work-directory)
- (define-key map [(control ? )] 'ido-restrict-to-matches)
+ (define-key map [(control ?\s)] 'ido-restrict-to-matches)
(define-key map [(control ?@)] 'ido-restrict-to-matches)
(define-key map [right] 'ido-next-match)
(define-key map [left] 'ido-prev-match)
(define-key map "?" 'ido-completion-help)
+ ;; Magic commands.
+ (define-key map "\C-b" 'ido-magic-backward-char)
+ (define-key map "\C-f" 'ido-magic-forward-char)
+ (define-key map "\C-d" 'ido-magic-delete-char)
+
(when (memq ido-cur-item '(file dir))
- (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 "\C-x\C-b" (or ido-context-switch-command 'ido-enter-switch-buffer))
+ (define-key map "\C-x\C-f" 'ido-fallback-command)
+ (define-key map "\C-x\C-d" (or (and ido-context-switch-command 'ignore) 'ido-enter-dired))
(define-key map [down] 'ido-next-match-dir)
(define-key map [up] 'ido-prev-match-dir)
(define-key map [(meta up)] 'ido-prev-work-directory)
(define-key map [(meta backspace)] 'ido-delete-backward-word-updir)
(define-key map [(control backspace)] 'ido-up-directory)
(define-key map "\C-l" 'ido-reread-directory)
- (define-key map [(meta ?b)] 'ido-next-work-file)
- (define-key map [(meta ?d)] 'ido-wide-find-dir)
- (define-key map [(meta ?f)] 'ido-wide-find-file)
+ (define-key map [(meta ?d)] 'ido-wide-find-dir-or-delete-dir)
+ (define-key map [(meta ?b)] 'ido-push-dir)
+ (define-key map [(meta ?f)] 'ido-wide-find-file-or-pop-dir)
(define-key map [(meta ?k)] 'ido-forget-work-directory)
(define-key map [(meta ?m)] 'ido-make-directory)
(define-key map [(meta ?n)] 'ido-next-work-directory)
(define-key map [(meta ?o)] 'ido-prev-work-file)
+ (define-key map [(meta control ?o)] 'ido-next-work-file)
(define-key map [(meta ?p)] 'ido-prev-work-directory)
(define-key map [(meta ?s)] 'ido-merge-work-directories)
)
)
(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-x\C-f" (or ido-context-switch-command 'ido-enter-find-file))
+ (define-key map "\C-x\C-b" 'ido-fallback-command)
(define-key map "\C-k" 'ido-kill-buffer-at-head)
)
(define-key map [remap viper-del-backward-char-in-insert] 'ido-delete-backward-updir)
(define-key map [remap viper-delete-backward-word] 'ido-delete-backward-word-updir)))
- (setq ido-mode-map map)
- (run-hooks 'ido-define-mode-map-hook)))
+ (setq ido-mode-map map)))
(defun ido-final-slash (dir &optional fix-it)
;; return DIR if DIR has final slash.
(ido-define-mode-map)
(setq ido-text-init initial)
+ (setq ido-input-stack nil)
+
+ (run-hooks 'ido-setup-hook)
+
(while (not done)
(ido-trace "\n_LOOP_" ido-text-init)
(setq ido-exit nil)
(l (ido-make-merged-file-list ido-text-init
(eq ido-use-merged-list 'auto)
(eq ido-try-merged-list 'wide))))
+ (ido-trace "merged" l)
(cond
((not l)
(if (eq ido-try-merged-list 'wide)
ido-use-merged-list nil)))
((eq l t)
(setq ido-use-merged-list nil))
+ ((eq l 'input-pending-p)
+ (setq ido-try-merged-list t
+ ido-use-merged-list nil))
(t
(setq ido-pre-merge-state
(list ido-text-init ido-current-directory olist oign omat))
(setq ido-text-init "")
(while new
(setq new (if edit
- (read-file-name (concat prompt "[EDIT] ")
- (expand-file-name d)
- (concat d f) nil f)
+ (condition-case nil
+ (read-file-name (concat prompt "[EDIT] ")
+ (expand-file-name d)
+ (concat d f) nil f)
+ (quit (concat d f)))
f)
d (or (file-name-directory new) "/")
f (file-name-nondirectory new)
(setq ido-text-init f
new nil))))))
(t
- (setq ido-text-init (read-string (concat prompt "[EDIT] ") ido-final-text))))
+ (setq ido-text-init
+ (condition-case nil
+ (read-string (concat prompt "[EDIT] ") ido-final-text)
+ (quit ido-final-text)))))
+
nil)
((eq ido-exit 'keep)
((memq ido-exit '(dired fallback find-file switch-to-buffer insert-buffer insert-file))
(setq done t))
- ((eq ido-exit 'updir)
+ ((memq ido-exit '(updir push))
;; cannot go up if already at the root-dir (Unix) or at the
;; root-dir of a certain drive (Windows or MS-DOS).
(if (ido-is-tramp-root)
(ido-set-current-directory (match-string 1 ido-current-directory))
(setq ido-set-default-item t))
(unless (ido-is-root-directory)
+ (when (eq ido-exit 'push)
+ (setq ido-input-stack (cons (cons ido-cur-item ido-text) ido-input-stack))
+ (setq ido-cur-item 'dir)
+ (setq ido-text-init (file-name-nondirectory (substring ido-current-directory 0 -1)))
+ (ido-trace "push" ido-input-stack))
(ido-set-current-directory (file-name-directory (substring ido-current-directory 0 -1)))
(setq ido-set-default-item t))))
+ ((eq ido-exit 'pop)
+ (ido-trace "pop" ido-input-stack)
+ (let ((elt (car ido-input-stack)))
+ (setq ido-input-stack (cdr ido-input-stack))
+ (ido-set-current-directory (concat ido-current-directory ido-text))
+ (setq ido-cur-item (car elt))
+ (setq ido-text-init (cdr elt))))
+
+ ((eq ido-exit 'pop-all)
+ (ido-trace "pop-all" ido-input-stack)
+ (while ido-input-stack
+ (let ((elt (car ido-input-stack)))
+ (setq ido-input-stack (cdr ido-input-stack))
+ (ido-set-current-directory (concat ido-current-directory ido-text))
+ (setq ido-cur-item (car elt))
+ (setq ido-text-init (cdr elt)))))
+
;; Handling the require-match must be done in a better way.
- ((and require-match (not (ido-existing-item-p)))
+ ((and require-match
+ (not (if ido-directory-too-big
+ (file-exists-p (concat ido-current-directory ido-final-text))
+ (ido-existing-item-p))))
(error "must specify valid item"))
(t
(ido-name (car ido-matches))))
(cond
- ((eq item 'buffer)
+ ((memq item '(buffer list))
(setq done t))
((string-equal "./" ido-selected)
(setq ido-last-directory-list
(cons (cons ido-current-directory ido-selected) ido-last-directory-list)))))
(ido-set-current-directory ido-current-directory ido-selected)
- (setq ido-set-default-item t))
+ (if ido-input-stack
+ (while ido-input-stack
+ (let ((elt (car ido-input-stack)))
+ (if (setq ido-input-stack (cdr ido-input-stack))
+ (ido-set-current-directory ido-current-directory (cdr elt))
+ (setq ido-text-init (cdr elt)))
+ (setq ido-cur-item (car elt))))
+ (setq ido-set-default-item t)))
(t
(setq done t))))))
(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))
+ (progn
+ (run-hook-with-args 'ido-before-fallback-functions
+ (or fallback 'switch-to-buffer))
+ (call-interactively (or fallback 'switch-to-buffer)))
(let* ((ido-context-switch-command switch-cmd)
(ido-current-directory nil)
(ido-directory-nonreadable nil)
((eq ido-exit 'fallback)
(let ((read-buffer-function nil))
+ (run-hook-with-args 'ido-before-fallback-functions
+ (or fallback 'switch-to-buffer))
(call-interactively (or fallback 'switch-to-buffer))))
;; Check buf is non-nil.
(if (eq method 'insert)
(progn
(ido-record-command 'insert-buffer buf)
- (insert-buffer buf))
+ (with-no-warnings
+ ;; we really want to run insert-buffer here
+ (insert-buffer buf)))
(ido-visit-buffer buf method t)))
;; buffer doesn't exist
;; 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-directory-too-big (and (not ido-directory-nonreadable)
- (ido-directory-too-big-p ido-current-directory)))
- (ido-context-switch-command switch-cmd)
- filename)
-
- (cond
- ((or (not ido-mode) (ido-is-slow-ftp-host))
- (setq filename t
- ido-exit 'fallback))
-
- ((and (eq item 'file)
+ (let ((ido-current-directory (ido-expand-directory default))
+ (ido-context-switch-command switch-cmd)
+ ido-directory-nonreadable ido-directory-too-big
+ (minibuffer-completing-file-name t)
+ filename)
+
+ (if (or (not ido-mode) (ido-is-slow-ftp-host))
+ (setq filename t
+ ido-exit 'fallback)
+ (setq 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))))
+
+ (when (and (eq item 'file)
(or ido-use-url-at-point ido-use-filename-at-point))
(let (fn d)
(require 'ffap)
;; Duplicate code from ffap-guesser as we want different behaviour for files and URLs.
(cond
- ((and ido-use-url-at-point
- ffap-url-regexp
- (ffap-fixup-url (or (ffap-url-at-point)
- (ffap-gopher-at-point))))
+ ((with-no-warnings
+ (and ido-use-url-at-point
+ ffap-url-regexp
+ (ffap-fixup-url (or (ffap-url-at-point)
+ (ffap-gopher-at-point)))))
(setq ido-exit 'ffap
filename t))
((and ido-use-filename-at-point
- (setq fn (ffap-string-at-point))
+ (setq fn (if (eq ido-use-filename-at-point 'guess)
+ (with-no-warnings (ffap-guesser))
+ (ffap-string-at-point)))
(not (string-match "^http:/" fn))
(setq d (file-name-directory fn))
(file-directory-p d))
(setq ido-current-directory d)
- (setq initial (file-name-nondirectory fn)))))))
+ (setq initial (file-name-nondirectory fn))))))
(let (ido-saved-vc-hb
(vc-handled-backends (and (boundp 'vc-handled-backends) vc-handled-backends))
;; we don't want to change directory of current buffer.
(let ((default-directory ido-current-directory)
(read-file-name-function nil))
+ (run-hook-with-args 'ido-before-fallback-functions
+ (or fallback 'find-file))
(call-interactively (or fallback 'find-file))))
((eq ido-exit 'switch-to-buffer)
(ido-record-work-directory)
(funcall method ido-current-directory)
(if (eq method 'dired)
- (dired-goto-file (expand-file-name file))))
+ (with-no-warnings
+ (dired-goto-file (expand-file-name file)))))
((string-match "[[*?]" filename)
(setq dirname (concat ido-current-directory filename))
(ido-record-command method dirname)
(setq filename (concat ido-current-directory filename))
(ido-record-command fallback filename)
(ido-record-work-directory)
+ (run-hook-with-args 'ido-before-fallback-functions fallback)
(funcall fallback filename))
((eq method 'insert)
(interactive)
(let (res)
(cond
+ (ido-incomplete-regexp
+ ;; Do nothing
+ )
((and (memq ido-cur-item '(file dir))
(string-match "[$]" ido-text))
(let ((evar (substitute-in-file-name (concat ido-current-directory ido-text))))
((not ido-use-merged-list)
(ido-merge-work-directories))))
+;;; Magic C-f
+
+(defun ido-magic-forward-char ()
+ "Move forward in user input or perform magic action.
+If no user input is present, or at end of input, perform magic actions:
+C-x C-b ... C-f switch to ido-find-file.
+C-x C-f ... C-f fallback to non-ido find-file.
+C-x C-d ... C-f fallback to non-ido brief dired.
+C-x d ... C-f fallback to non-ido dired."
+ (interactive)
+ (cond
+ ((not (eobp))
+ (forward-char 1))
+ ((memq ido-cur-item '(file dir))
+ (ido-fallback-command))
+ (ido-context-switch-command
+ (call-interactively ido-context-switch-command))
+ ((eq ido-cur-item 'buffer)
+ (ido-enter-find-file))))
+
+;;; Magic C-b
+
+(defun ido-magic-backward-char ()
+ "Move backward in user input or perform magic action.
+If no user input is present, or at start of input, perform magic actions:
+C-x C-f C-b switch to ido-switch-buffer.
+C-x C-d C-b switch to ido-switch-buffer.
+C-x d C-b switch to ido-switch-buffer.
+C-x C-b C-b fallback to non-ido switch-to-buffer."
+ (interactive)
+ (cond
+ ((> (point) (minibuffer-prompt-end))
+ (forward-char -1))
+ ((eq ido-cur-item 'buffer)
+ (ido-fallback-command))
+ (ido-context-switch-command
+ (call-interactively ido-context-switch-command))
+ (t
+ (ido-enter-switch-buffer))))
+
+;;; Magic C-d
+
+(defun ido-magic-delete-char ()
+ "Delete following char in user input or perform magic action.
+If at end of user input, perform magic actions:
+C-x C-f ... C-d enter dired on current directory."
+ (interactive)
+ (cond
+ ((not (eobp))
+ (delete-char 1))
+ (ido-context-switch-command
+ nil)
+ ((memq ido-cur-item '(file dir))
+ (ido-enter-dired))))
+
+
;;; TOGGLE FUNCTIONS
(defun ido-toggle-case ()
(defun ido-exit-minibuffer ()
"Exit minibuffer, but make sure we have a match if one is needed."
(interactive)
- (if (or (not ido-require-match)
- (ido-existing-item-p))
- (throw 'exit nil)))
+ (if (and (or (not ido-require-match)
+ (ido-existing-item-p))
+ (not ido-incomplete-regexp))
+ (exit-minibuffer)))
(defun ido-select-text ()
"Select the buffer or file named by the prompt.
(defun ido-fallback-command ()
"Fallback to non-ido version of current command."
(interactive)
+ (let ((i (length ido-text)))
+ (while (> i 0)
+ (push (aref ido-text (setq i (1- i))) unread-command-events)))
(setq ido-exit 'fallback)
(exit-minibuffer))
(defun ido-enter-find-file ()
- "Drop into find-file from buffer switching."
+ "Drop into `find-file' from buffer switching."
(interactive)
(setq ido-exit 'find-file)
(exit-minibuffer))
(defun ido-enter-switch-buffer ()
- "Drop into ido-switch-buffer from file switching."
+ "Drop into `ido-switch-buffer' from file switching."
(interactive)
(setq ido-exit 'switch-to-buffer)
(exit-minibuffer))
(file-directory-p dir)
(or (not must-match)
;; TODO. check for nonreadable and too-big.
- (ido-set-matches1
+ (ido-set-matches-1
(if (eq ido-cur-item 'file)
- (ido-make-file-list1 dir)
- (ido-make-dir-list1 dir)))))
+ (ido-make-file-list-1 dir)
+ (ido-make-dir-list-1 dir)))))
(setq j n)
(setq dir nil)))
(if dir
(unless file
(let ((enable-recursive-minibuffers t))
(setq file
- (read-string (concat "Wide find file: " ido-current-directory) ido-text))))
+ (condition-case nil
+ (read-string (concat "Wide find file: " ido-current-directory) ido-text)
+ (quit "")))))
(when (> (length file) 0)
(setq ido-use-merged-list t ido-try-merged-list 'wide)
(setq ido-exit 'refresh)
(unless dir
(let ((enable-recursive-minibuffers t))
(setq dir
- (read-string (concat "Wide find directory: " ido-current-directory) ido-text))))
+ (condition-case nil
+ (read-string (concat "Wide find directory: " ido-current-directory) ido-text)
+ (quit "")))))
(when (> (length dir) 0)
(setq ido-use-merged-list t ido-try-merged-list 'wide)
(setq ido-exit 'refresh)
(setq ido-rotate-temp t)
(exit-minibuffer)))
+(defun ido-wide-find-dir-or-delete-dir (&optional dir)
+ "Prompt for DIR to search for using find, starting from current directory.
+If input stack is non-empty, delete current directory component."
+ (interactive)
+ (if ido-input-stack
+ (ido-delete-backward-word-updir 1)
+ (ido-wide-find-dir)))
+
+(defun ido-push-dir ()
+ "Move to previous directory in file name, push current input on stack."
+ (interactive)
+ (setq ido-exit 'push)
+ (exit-minibuffer))
+
+(defun ido-pop-dir (arg)
+ "Pop directory from input stack back to input.
+With \\[universal-argument], pop all element."
+ (interactive "P")
+ (when ido-input-stack
+ (setq ido-exit (if arg 'pop-all 'pop))
+ (exit-minibuffer)))
+
+(defun ido-wide-find-file-or-pop-dir (arg)
+ (interactive "P")
+ (if ido-input-stack
+ (ido-pop-dir arg)
+ (ido-wide-find-file)))
+
(defun ido-make-directory (&optional dir)
"Prompt for DIR to create in current directory."
(interactive)
(ido-directory-too-big nil))
(cond
((eq ido-cur-item 'file)
- (ido-make-file-list1 ido-current-directory))
+ (ido-make-file-list-1 ido-current-directory))
((eq ido-cur-item 'dir)
- (ido-make-dir-list1 ido-current-directory))
+ (ido-make-dir-list-1 ido-current-directory))
((eq ido-cur-item 'buffer)
- (ido-make-buffer-list1))
+ (ido-make-buffer-list-1))
((eq ido-cur-item 'list)
ido-choice-list)
(t nil))))
-(defun ido-sort-list (items)
- ;; Simple list of file or buffer names
- (sort items (lambda (a b) (string-lessp (ido-no-final-slash a)
- (ido-no-final-slash b)))))
+;; File list sorting
+
+(defun ido-file-lessp (a b)
+ ;; Simple compare two file names.
+ (string-lessp (ido-no-final-slash a) (ido-no-final-slash b)))
+
+
+(defun ido-file-extension-lessp (a b)
+ ;; Compare file names according to ido-file-extensions-order list.
+ (let ((n (compare-strings a 0 nil b 0 nil nil))
+ lessp p)
+ (if (eq n t)
+ nil
+ (if (< n 0)
+ (setq n (1- (- n))
+ p a a b b p
+ lessp t)
+ (setq n (1- n)))
+ (cond
+ ((= n 0)
+ lessp)
+ ((= (aref a n) ?.)
+ (ido-file-extension-aux a b n lessp))
+ (t
+ (while (and (> n 2) (/= (aref a n) ?.))
+ (setq n (1- n)))
+ (if (> n 1)
+ (ido-file-extension-aux a b n lessp)
+ lessp))))))
+
+(defun ido-file-extension-aux (a b n lessp)
+ (let ((oa (ido-file-extension-order a n))
+ (ob (ido-file-extension-order b n)))
+ (cond
+ ((= oa ob)
+ lessp)
+ ((and oa ob)
+ (if lessp
+ (> oa ob)
+ (< oa ob)))
+ (oa
+ (not lessp))
+ (ob
+ lessp)
+ (t
+ lessp))))
+
+(defun ido-file-extension-order (s n)
+ (let ((l ido-file-extensions-order)
+ (i 0) o do)
+ (while l
+ (cond
+ ((eq (car l) t)
+ (setq do i
+ l (cdr l)))
+ ((eq (compare-strings s n nil (car l) 0 nil nil) t)
+ (setq o i
+ l nil))
+ (t
+ (setq l (cdr l))))
+ (setq i (1+ i)))
+ (or o do)))
+
(defun ido-sort-merged-list (items promote)
;; Input is list of ("file" . "dir") cons cells.
(setq items (cdr items)))
res))
-(defun ido-make-merged-file-list (text auto wide)
+
+(defun ido-make-merged-file-list-1 (text auto wide)
(let (res)
- (message "Searching for `%s'...." text)
(if (and (ido-final-slash text) ido-dir-file-cache)
(if wide
(setq res (ido-wide-find-dirs-or-files
(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))))
+ (ido-make-file-list-1 dir t)
+ (ido-make-dir-list-1 dir t))))
(if must-match
- (setq fl (ido-set-matches1 fl)))
+ (setq fl (ido-set-matches-1 fl)))
(if fl
(setq res (nconc fl res))))
(if (and auto (input-pending-p))
(setq dirs nil
res t))))))
- (if (and res (not (eq res t)))
- (setq res (ido-sort-merged-list res auto)))
+ res))
+
+(defun ido-make-merged-file-list (text auto wide)
+ (let (res)
+ (message "Searching for `%s'...." text)
+ (condition-case nil
+ (if (eq t (setq res
+ (while-no-input
+ (ido-make-merged-file-list-1 text auto wide))))
+ (setq res 'input-pending-p))
+ (quit
+ (setq res t
+ ido-try-merged-list nil
+ ido-use-merged-list nil)))
+ (when (and res (listp res))
+ (setq res (ido-sort-merged-list res auto)))
(when (and (or ido-rotate-temp ido-rotate-file-list-default)
(listp res)
(> (length text) 0))
(message nil)
res))
-(defun ido-make-buffer-list1 (&optional frame visible)
+(defun ido-make-buffer-list-1 (&optional frame visible)
;; Return list of non-ignored buffer names
(delq nil
(mapcar
(defun ido-make-buffer-list (default)
;; Return the current list of buffers.
;; Currently visible buffers are put at the end of the list.
- ;; The hook `ido-make-buflist-hook' is run after the list has been
+ ;; The hook `ido-make-buffer-list-hook' is run after the list has been
;; created to allow the user to further modify the order of the buffer names
;; in this list. If DEFAULT is non-nil, and corresponds to an existing buffer,
;; it is put to the start of the list.
(let* ((ido-current-buffers (ido-get-buffers-in-frames 'current))
- (ido-temp-list (ido-make-buffer-list1 (selected-frame) ido-current-buffers)))
+ (ido-temp-list (ido-make-buffer-list-1 (selected-frame) ido-current-buffers)))
(if ido-temp-list
(nconc ido-temp-list ido-current-buffers)
(setq ido-temp-list ido-current-buffers))
(nconc ido-temp-list items)
(setq ido-temp-list items)))
-(defun ido-file-name-all-completions1 (dir)
+(defun ido-file-name-all-completions-1 (dir)
(cond
((ido-nonreadable-directory-p dir) '())
;; do not check (ido-directory-too-big-p dir) here.
(if (and ftp (file-readable-p dir))
(setq mtime (cons 'ftp (ido-time-stamp))))
(if mtime
- (setq cached (cons dir (cons mtime (ido-file-name-all-completions1 dir)))
+ (setq cached (cons dir (cons mtime (ido-file-name-all-completions-1 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))))
- (ido-file-name-all-completions1 dir)))
+ (ido-file-name-all-completions-1 dir)))
(defun ido-remove-cached-dir (dir)
;; Remove dir from ido-dir-file-cache
(setq ido-dir-file-cache (delq cached ido-dir-file-cache))))))
-(defun ido-make-file-list1 (dir &optional merged)
+(defun ido-make-file-list-1 (dir &optional merged)
;; Return list of non-ignored files in DIR
;; If MERGED is non-nil, each file is cons'ed with DIR
(and (or (ido-is-tramp-root dir) (file-directory-p dir))
;; The hook `ido-make-file-list-hook' is run after the list has been
;; created to allow the user to further modify the order of the file names
;; in this list.
- (let ((ido-temp-list (ido-make-file-list1 ido-current-directory)))
- (setq ido-temp-list (ido-sort-list ido-temp-list))
+ (let ((ido-temp-list (ido-make-file-list-1 ido-current-directory)))
+ (setq ido-temp-list (sort ido-temp-list
+ (if ido-file-extensions-order
+ #'ido-file-extension-lessp
+ #'ido-file-lessp)))
(let ((default-directory ido-current-directory))
(ido-to-end ;; move ftp hosts and visited files to end
(delq nil (mapcar
(run-hooks 'ido-make-file-list-hook)
ido-temp-list))
-(defun ido-make-dir-list1 (dir &optional merged)
+(defun ido-make-dir-list-1 (dir &optional merged)
;; Return list of non-ignored subdirs in DIR
;; If MERGED is non-nil, each subdir is cons'ed with DIR
(and (or (ido-is-tramp-root dir) (file-directory-p dir))
;; The hook `ido-make-dir-list-hook' is run after the list has been
;; created to allow the user to further modify the order of the
;; directory names in this list.
- (let ((ido-temp-list (ido-make-dir-list1 ido-current-directory)))
- (setq ido-temp-list (ido-sort-list ido-temp-list))
+ (let ((ido-temp-list (ido-make-dir-list-1 ido-current-directory)))
+ (setq ido-temp-list (sort ido-temp-list #'ido-file-lessp))
(ido-to-end ;; move . files to end
(delq nil (mapcar
(lambda (x) (if (string-equal (substring x 0 1) ".") x))
(setq ido-temp-list
(cons default ido-temp-list))))
(setq ido-temp-list (delete "." ido-temp-list))
- (setq ido-temp-list (cons "." ido-temp-list))
+ (unless ido-input-stack
+ (setq ido-temp-list (cons "." ido-temp-list)))
(run-hooks 'ido-make-dir-list-hook)
ido-temp-list))
;;; FIND MATCHING ITEMS
-(defun ido-set-matches1 (items &optional do-full)
+(defun ido-set-matches-1 (items &optional do-full)
;; Return list of matches in items
(let* ((case-fold-search ido-case-fold)
(slash (and (not ido-enable-prefix) (ido-final-slash ido-text)))
full-matches
prefix-matches
matches)
- (mapcar
- (lambda (item)
- (let ((name (ido-name item)))
- (if (and (or non-prefix-dot
- (if (= (aref ido-text 0) ?.)
- (= (aref name 0) ?.)
- (/= (aref name 0) ?.)))
- (string-match re name))
- (cond
- ((and full-re (string-match full-re name))
- (setq full-matches (cons item full-matches)))
- ((and prefix-re (string-match prefix-re name))
- (setq prefix-matches (cons item prefix-matches)))
- (t (setq matches (cons item matches))))))
- t)
- items)
+ (setq ido-incomplete-regexp nil)
+ (condition-case error
+ (mapcar
+ (lambda (item)
+ (let ((name (ido-name item)))
+ (if (and (or non-prefix-dot
+ (if (= (aref ido-text 0) ?.)
+ (= (aref name 0) ?.)
+ (/= (aref name 0) ?.)))
+ (string-match re name))
+ (cond
+ ((and full-re (string-match full-re name))
+ (setq full-matches (cons item full-matches)))
+ ((and prefix-re (string-match prefix-re name))
+ (setq prefix-matches (cons item prefix-matches)))
+ (t (setq matches (cons item matches))))))
+ t)
+ items)
+ (invalid-regexp
+ (setq ido-incomplete-regexp t
+ ;; Consider the invalid regexp message internally as a
+ ;; special-case single match, and handle appropriately
+ ;; elsewhere.
+ matches (cdr error))))
(if prefix-matches
(setq matches (nconc prefix-matches matches)))
(if full-matches
(defun ido-set-matches ()
;; Set `ido-matches' to the list of items matching prompt
(when ido-rescan
- (setq ido-matches (ido-set-matches1 (reverse ido-cur-list) (not ido-rotate))
+ (setq ido-matches (ido-set-matches-1 (reverse ido-cur-list) (not ido-rotate))
ido-rotate nil)))
(defun ido-ignore-item-p (name re-list &optional ignore-ext)
(or (member name ido-ignore-item-temp-list)
(and
ido-process-ignore-lists re-list
- (let ((data (match-data))
- (ext-list (and ignore-ext ido-ignore-extensions
+ (save-match-data
+ (let ((ext-list (and ignore-ext ido-ignore-extensions
completion-ignored-extensions))
- ignorep nextstr
- (flen (length name)) slen)
- (while ext-list
- (setq nextstr (car ext-list))
- (if (cond
- ((stringp nextstr)
- (and (>= flen (setq slen (length nextstr)))
- (string-equal (substring name (- flen slen)) nextstr)))
- ((fboundp nextstr) (funcall nextstr name))
- (t nil))
- (setq ignorep t
- ext-list nil
- re-list nil)
- (setq ext-list (cdr ext-list))))
- (while re-list
- (setq nextstr (car re-list))
- (if (cond
- ((stringp nextstr) (string-match nextstr name))
- ((fboundp nextstr) (funcall nextstr name))
- (t nil))
- (setq ignorep t
- re-list nil)
- (setq re-list (cdr re-list))))
- ;; return the result
- (if ignorep
- (setq ido-ignored-list (cons name ido-ignored-list)))
- (set-match-data data)
- ignorep))))
-
+ (case-fold-search ido-case-fold)
+ ignorep nextstr
+ (flen (length name)) slen)
+ (while ext-list
+ (setq nextstr (car ext-list))
+ (if (cond
+ ((stringp nextstr)
+ (and (>= flen (setq slen (length nextstr)))
+ (string-equal (substring name (- flen slen)) nextstr)))
+ ((fboundp nextstr) (funcall nextstr name))
+ (t nil))
+ (setq ignorep t
+ ext-list nil
+ re-list nil)
+ (setq ext-list (cdr ext-list))))
+ (while re-list
+ (setq nextstr (car re-list))
+ (if (cond
+ ((stringp nextstr) (string-match nextstr name))
+ ((fboundp nextstr) (funcall nextstr name))
+ (t nil))
+ (setq ignorep t
+ re-list nil)
+ (setq re-list (cdr re-list))))
+ ;; return the result
+ (if ignorep
+ (setq ido-ignored-list (cons name ido-ignored-list)))
+ ignorep)))))
;; Private variable used by `ido-word-matching-substring'.
(defvar ido-change-word-sub)
(if (pos-visible-in-window-p (point-max) win)
(if (or ido-completion-buffer-all-completions (boundp 'ido-completion-buffer-full))
(set-window-start win (point-min))
- (set (make-local-variable 'ido-completion-buffer-full) t)
+ (with-no-warnings
+ (set (make-local-variable 'ido-completion-buffer-full) t))
(setq full-list t
display-it t))
(scroll-other-window))
(setq display-it t))
(if display-it
(with-output-to-temp-buffer ido-completion-buffer
- (let ((completion-list (ido-sort-list
+ (let ((completion-list (sort
(cond
(ido-use-merged-list
(ido-flatten-merged-list (or ido-matches ido-cur-list)))
((or full-list ido-completion-buffer-all-completions)
(ido-all-completions))
(t
- (copy-sequence (or ido-matches ido-cur-list)))))))
+ (copy-sequence (or ido-matches ido-cur-list))))
+ #'ido-file-lessp)))
(if (featurep 'xemacs)
;; XEmacs extents are put on by default, doesn't seem to be
;; any way of switching them off.
;;; VISIT CHOSEN BUFFER
(defun ido-visit-buffer (buffer method &optional record)
"Visit file named FILE according to METHOD.
-Record command in command-history if optional RECORD is non-nil."
+Record command in `command-history' if optional RECORD is non-nil."
(let (win newframe)
(cond
As you type in a string, all of the buffers matching the string are
displayed if substring-matching is used \(default). Look at
-`ido-enable-prefix' and `ido-toggle-prefix'. When you have found the
-buffer you want, it can then be selected. As you type, most keys have their
-normal keybindings, except for the following: \\<ido-mode-map>
+`ido-enable-prefix' and `ido-toggle-prefix'. When you have found the
+buffer you want, it can then be selected. As you type, most keys have
+their normal keybindings, except for the following: \\<ido-mode-map>
RET Select the buffer at the front of the list of matches. If the
list is empty, possibly prompt to create new buffer.
default is to show it in the same window, unless it is already
visible in another frame.
-The file name is selected interactively by typing a substring. As you type
-in a string, all of the filenames matching the string are displayed if
-substring-matching is used \(default). Look at `ido-enable-prefix' and
-`ido-toggle-prefix'. When you have found the filename you want, it can
-then be selected. As you type, most keys have their normal keybindings,
+The file name is selected interactively by typing a substring. As you
+type in a string, all of the filenames matching the string are displayed
+if substring-matching is used \(default). Look at `ido-enable-prefix' and
+`ido-toggle-prefix'. When you have found the filename you want, it can
+then be selected. As you type, most keys have their normal keybindings,
except for the following: \\<ido-mode-map>
RET Select the file at the front of the list of matches. If the
(ido-set-matches)
(ido-trace "new " ido-matches)
- (when (and ido-enter-single-matching-directory
+ (when (and ido-enter-matching-directory
ido-matches
- (null (cdr ido-matches))
+ (or (eq ido-enter-matching-directory 'first)
+ (null (cdr ido-matches)))
(ido-final-slash (car ido-matches))
(or try-single-dir-match
- (eq ido-enter-single-matching-directory t)))
+ (eq ido-enter-matching-directory t)))
(ido-trace "single match" (car ido-matches))
(ido-set-current-directory
(concat ido-current-directory (car ido-matches)))
first)
(if (and ind ido-use-faces)
- (put-text-property 0 1 'face 'ido-indicator-face ind))
+ (put-text-property 0 1 'face 'ido-indicator ind))
(if (and ido-use-faces comps)
(let* ((fn (ido-name (car comps)))
(setq first (format "%s" fn))
(put-text-property 0 ln 'face
(if (= (length comps) 1)
- 'ido-only-match-face
- 'ido-first-match-face)
+ (if ido-incomplete-regexp
+ 'ido-incomplete-regexp
+ 'ido-only-match)
+ 'ido-first-match)
first)
(if ind (setq first (concat first ind)))
(setq comps (cons first (cdr comps)))))
(ido-report-no-match
(nth 6 ido-decorations)) ;; [No match]
(t "")))
-
+ (ido-incomplete-regexp
+ (concat " " (car comps)))
((null (cdr comps)) ;one match
- (concat (if (> (length (ido-name (car comps))) (length name))
- ;; when there is one match, show the matching file name in full
- (concat (nth 4 ido-decorations) ;; [ ... ]
- (ido-name (car comps))
- (nth 5 ido-decorations))
- "")
+ (concat (if (if (not ido-enable-regexp)
+ (= (length (ido-name (car comps))) (length name))
+ ;; We can't rely on the length of the input
+ ;; for regexps, so explicitly check for a
+ ;; complete match
+ (string-match name (ido-name (car comps)))
+ (string-equal (match-string 0 (ido-name (car comps)))
+ (ido-name (car comps))))
+ ""
+ ;; when there is one match, show the matching file name in full
+ (concat (nth 4 ido-decorations) ;; [ ... ]
+ (ido-name (car comps))
+ (nth 5 ido-decorations)))
(if (not ido-use-faces) (nth 7 ido-decorations)))) ;; [Matched]
(t ;multiple matches
(let* ((items (if (> ido-max-prospects 0) (1+ ido-max-prospects) 999))
(if (and ido-use-faces
(not (string= str first))
(ido-final-slash str))
- (put-text-property 0 (length str) 'face 'ido-subdir-face str))
+ (put-text-property 0 (length str) 'face 'ido-subdir str))
str)))))
comps))))))
;;; Helper functions for other programs
(put 'dired-do-rename 'ido 'ignore)
+(put 'ibuffer-find-file 'ido 'find-file)
+(put 'dired-other-window 'ido 'dir)
;;;###autoload
(defun ido-read-buffer (prompt &optional default require-match)
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 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)
(buf (ido-read-internal 'buffer prompt 'ido-buffer-history default require-match)))
(if (eq ido-exit 'fallback)
(let ((read-buffer-function nil))
+ (run-hook-with-args 'ido-before-fallback-functions 'read-buffer)
(read-buffer prompt default require-match))
buf)))
(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)))
+ (ido-read-directory-name prompt dir default-filename mustmatch initial))
+ (if (eq ido-exit 'fallback)
+ (setq filename 'fallback)))
((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)
+ (ido-context-switch-command
+ (if (eq (get this-command 'ido) 'find-file) nil 'ignore))
(vc-handled-backends (and (boundp 'vc-handled-backends) vc-handled-backends))
+ (minibuffer-completing-file-name t)
(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)
(cond
((eq ido-exit 'fallback)
(setq filename 'fallback))
+ ((eq ido-exit 'dired)
+ (setq filename ido-current-directory))
(filename
(setq filename
(concat ido-current-directory filename))))))
(setq filename 'fallback)))
(if (eq filename 'fallback)
(let ((read-file-name-function nil))
+ (run-hook-with-args 'ido-before-fallback-functions 'read-file-name)
(read-file-name prompt dir default-filename mustmatch initial predicate))
filename)))
Read directory name, prompting with PROMPT and completing in directory DIR.
See `read-directory-name' for additional parameters."
(let* (filename
+ (minibuffer-completing-file-name t)
(ido-context-switch-command 'ignore)
ido-saved-vc-hb
(ido-current-directory (ido-expand-directory dir))