;;; ido.el --- interactively do things with buffers and files.
;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
-;; 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+;; 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
;; Author: Kim F. Storm <storm@cua.dk>
;; Based on: iswitchb by Stephen Eglen <stephen@cns.ed.ac.uk>
;; Stores the current list of items that will be searched through.
;; The list is ordered, so that the most interesting item comes first,
;; although by default, the files visible in the current frame are put
-;; at the end of the list. Created by `ido-make-item-list'.
-(defvar ido-cur-list)
+;; at the end of the list.
+(defvar ido-cur-list nil)
;; Stores the choice list for ido-completing-read
-(defvar ido-choice-list)
+(defvar ido-choice-list nil)
;; Stores the list of items which are ignored when building
;; `ido-cur-list'. It is in no specific order.
(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 behavior for files and URLs.
+ ;; Duplicate code from ffap-guesser as we want different
+ ;; behavior for files and URLs.
(cond
((with-no-warnings
(and ido-use-url-at-point
(ffap-guesser)
(ffap-string-at-point))))
(not (string-match "^http:/" fn))
- (setq d (file-name-directory fn))
+ (let ((absolute-fn (expand-file-name fn)))
+ (setq d (if (file-directory-p absolute-fn)
+ (file-name-as-directory absolute-fn)
+ (file-name-directory absolute-fn))))
(file-directory-p d))
(setq ido-current-directory d)
(setq initial (file-name-nondirectory fn))))))
(defun ido-copy-current-word (all)
"Insert current word (file or directory name) from current buffer."
(interactive "P")
- (let ((word (save-excursion
- (set-buffer ido-entry-buffer)
+ (let ((word (with-current-buffer ido-entry-buffer
(let ((p (point)) start-line end-line start-name name)
(if (and mark-active (/= p (mark)))
(setq start-name (mark))
(if ido-temp-list
(nconc ido-temp-list ido-current-buffers)
(setq ido-temp-list ido-current-buffers))
- (if default
+ (if (and default (buffer-live-p (get-buffer default)))
(progn
(setq ido-temp-list
(delete default ido-temp-list))
;; Used by `ido-get-buffers-in-frames' to walk through all windows
(let ((buf (buffer-name (window-buffer win))))
(unless (or (member buf ido-bufs-in-frame)
+ (minibufferp buf)
(member buf ido-ignore-item-temp-list))
;; Only add buf if it is not already in list.
;; This prevents same buf in two different windows being
;; Return dotted pair (RES . 1).
(cons res 1))
-(defun ido-choose-completion-string (choice buffer mini-p base-size)
+(defun ido-choose-completion-string (choice &rest ignored)
(when (ido-active)
;; Insert the completion into the buffer where completion was requested.
(if (get-buffer ido-completion-buffer)
;;(add-hook 'completion-setup-hook 'completion-setup-function)
(display-completion-list completion-list)))))))
+(defun ido-kill-buffer-internal (buf)
+ "Kill buffer BUF and rebuild ido's buffer list if needed."
+ (if (not (kill-buffer buf))
+ ;; buffer couldn't be killed.
+ (setq ido-rescan t)
+ ;; else buffer was killed so remove name from list.
+ (setq ido-cur-list (delq buf ido-cur-list))
+ ;; Some packages, like uniquify.el, may rename buffers when one
+ ;; is killed, so we need to test this condition to avoid using
+ ;; an outdated list of buffer names. We don't want to always
+ ;; rebuild the list of buffers, as this alters the previous
+ ;; buffer order that the user was seeing on the prompt. However,
+ ;; when we rebuild the list, we try to keep the previous second
+ ;; buffer as the first one.
+ (catch 'update
+ (dolist (b ido-cur-list)
+ (unless (get-buffer b)
+ (setq ido-cur-list (ido-make-buffer-list (cadr ido-matches)))
+ (setq ido-rescan t)
+ (throw 'update nil))))))
+
;;; KILL CURRENT BUFFER
(defun ido-kill-buffer-at-head ()
"Kill the buffer at the head of `ido-matches'.
(let ((enable-recursive-minibuffers t)
(buf (ido-name (car ido-matches))))
(when buf
- (kill-buffer buf)
+ (ido-kill-buffer-internal buf)
;; Check if buffer still exists.
(if (get-buffer buf)
;; buffer couldn't be killed.
((eq method 'kill)
(if record
(ido-record-command 'kill-buffer buffer))
- (kill-buffer buffer))
+ (ido-kill-buffer-internal buffer))
((eq method 'other-window)
(if record
ido-text-init contents
ido-rotate-temp t
ido-exit 'refresh)
- (save-excursion
- (set-buffer buffer)
+ (with-current-buffer buffer
(ido-tidy))
(throw 'ido contents))))