Subject: Re: bug#7231: 23.3; Don't rebuild buffer list in iswitchb-visit-buffer

From: Leo <[email-masked]>
Date: Wed, 20 Oct 2010 12:53:49 +0800

Hello Stefan,

On 2010-10-20 11:00 +0800, Leo wrote:
> On 2010-10-18 22:54 +0800, Stefan Monnier wrote:
>> I was about to install that change when I realized that this is
>> fundamentally not the right approach: since some of the buffers may have
>> changed name, the new list of matching buffers may be different (some
>> buffers that didn't match before may match now and vice-versa).
>>
>> So iswitchb-make-buflist is more correct.  To deal with the problem of
>> ordering, we'll need to combine the two: call iswitchb-make-buflist to
>> get the new list of matches, and then use bufobjs to sort the new
>> iswitchb-buflist.
>
> My understanding seems to be:
>
> iswitchb-buflist already contains all buffers needed although its order
> can be modified by iswitchb-next/prev-match. That modified ordering info
> is lost after iswitchb-make-buflist. There may be new matches appearing
> due to buffer name changes but this is taken care of automatically by
> iswitchb-exhibit.
>
> Leo

If the proposed solution to iswitchb is acceptable, a similar one should
be done for ido.

Here is a patch to be applied on top of
http://debbugs.gnu.org/cgi/bugreport.cgi?bug=6943.

>From 5686c7c723d9bad601d870aff54b7a3d8edce471 Mon Sep 17 00:00:00 2001
Date: Wed, 20 Oct 2010 12:17:53 +0800
Subject: [PATCH] Don't rebuild buffer list in ido-kill-buffer-at-head

Rebuilding buffer list will lose the order of matches seen by the user
in particular when it has been rotated.
---
 lisp/ido.el |   32 ++++++++++++++------------------
 1 files changed, 14 insertions(+), 18 deletions(-)

diff --git a/lisp/ido.el b/lisp/ido.el
index 4a60288..d913069 100644
--- a/lisp/ido.el
+++ b/lisp/ido.el
@@ -3978,26 +3978,22 @@ If cursor is not at the end of the user input, delete to end of input."
   (if (not (eobp))
       (delete-region (point) (line-end-position))
     (let ((enable-recursive-minibuffers t)
-	  (buf (ido-name (car ido-matches)))
-	  (nextbuf (cadr ido-matches)))
+	  (buf (ido-name (car ido-matches))))
       (cond
        ((get-buffer buf)
-	;; If next match names a buffer use the buffer object; buffer
-	;; name may be changed by packages such as uniquify.
-	(when (and nextbuf (get-buffer nextbuf))
-	  (setq nextbuf (get-buffer nextbuf)))
-	(if (null (kill-buffer buf))
-	    ;; Buffer couldn't be killed.
-	    (setq ido-rescan t)
-	  ;; Else `kill-buffer' succeeds so re-make the buffer list
-	  ;; taking into account packages like uniquify may rename
-	  ;; buffers.
-	  (if (bufferp nextbuf)
-	      (setq nextbuf (buffer-name nextbuf)))
-	  (setq ido-default-item nextbuf
-		ido-text-init ido-text
-		ido-exit 'refresh)
-	  (exit-minibuffer)))
+	;; Note that some packages (eg uniquify.el) may change buffer
+	;; names. So save a list of buffer objects.
+	(let ((bufobjs (mapcar (lambda (name)
+				 (or (get-buffer name) name))
+			       ido-cur-list)))
+	  (if (null (kill-buffer buf))
+	      ;; Buffer couldn't be killed.
+	      (setq ido-rescan t)
+	    (setq ido-cur-list
+		  (delq nil (mapcar (lambda (b) (if (bufferp b)
+						    (buffer-name b)
+						  b))
+				    bufobjs))))))
        ;; Handle virtual buffers
        ((assoc buf ido-virtual-buffers)
 	(setq recentf-list
-- 
1.7.3