Subject: bug#11556: 24.0.97; Strange behaviour of bury-buffer after desktop-read

From: martin rudalics <[email-masked]>
Date: Sun, 27 May 2012 15:20:00 +0200

> I recently switched from Emacs 23 to the current version on the emacs-24
 > branch (r108014) and bumped into a strange behaviour of bury-buffer at
 > the start of a session. I'm using desktop.el and (global-set-key "\C-xy"
 > 'bury-buffer) in .emacs (because I have a bad memory and like to bury
 > stuff ;-). Every time I start Emacs, I see the correct buffer, i.e. the
 > one I used before I closed Emacs previously.

This is accomplished by this form

	    (switch-to-buffer (car (buffer-list)))

in `desktop-read'.

 > I edit that buffer a bit
 > and bury it. In my case, bury-buffer switches to the wrong buffer.
 > Instead of switching to the buffer next in line (so to speak),
 > bury-buffer switches to what seems to be the last buffer in the list of
 > all buffers.
 >
 > Here's a little example in form of a "emacs -Q" recipe:
 > 3 C-x C-s 3 RET
 > C-x b 2 RET
 > 2 C-x C-s 2 RET
 > C-x b 1 RET
 > 1 C-x C-s 1 RET
 > M-x desktop-save <filename>
 >
 > This should leave you with with three saved buffers in the order 1-2-3
 > and a desktop file. C-x C-b should be able to confirm the buffer order.
 >
 > Now close Emacs, start a fresh one and M-x desktop-read your desktop
 > file. You should see buffer 1. So far, so good. Now M-x bury-buffer. I'd
 > expect to see buffer 2 now, instead Emacs switched to buffer 3. If you
 > C-x C-b now, you'll see that the buffer list says that buffer 2 is up
 > front, although you're staring at buffer 3. This bug hits you only at
 > the very beginning of a session. I can continue to bury buffers using
 > C-x y and end up with buffers apparently from the end of the buffer
 > list, instead of from the top.

What happens is this: The buffer section of .emacs.desktop lists buffers
"in same order as in buffer list".  Processing these in your case means
processing 1 then 2 then 3.  `desktop-restore-file-buffer', which is
implicitly called in this process, switches to 1, 2 and 3 in this order
in the selected window.  This means that the last buffer shown in the
window is 3.  After that, the above mentioned `switch-to-buffer' from
`desktop-read' switches to buffer 1.  Burying that buffer shows the last
buffer shown in the selected window which is 3 and not 2 as expected.

 > But some actions fix this, like switching
 > a buffer once using C-x b. Afterwards the bug is nowhere to be found.

Since the corruption happens once only when processing .emacs.desktop.

 > The last few days I started work with a strange
 > I-could-swear-that-wasnt-the-file-I-was-working-on-yesterday-before-I-went-home
 > feeling :-D. Any ideas on how to get rid of that feeling are very
 > welcome :-).

The bug is obviously a regression with respect to Emacs 23.1 so we
should fix it.  One possible approach is to remove the buffer switching
done in `desktop-restore-file-buffer' which apparently should have the
sole reason to affect the buffer list while somehow preserving the
history of buffers that have been shown before calling `desktop-read'.
But I'm completely ignorant of desktop's handling of the buffer list
which involves some 14 calls to `bury-buffer' for restoring just three
buffers here.  If someone competent in this area could tell us how to
simplify this, I'd be all ears.

Eventually, we should handle this when restoring the windows from the
previous session but the question remains how to handle previously shown
buffers correctly when doing `desktop-read' in the middle of a session.

Meanwhile I can offer the attached brute force fix which kills the
individual history of all windows but should leave the buffer lists in
place.  Note that I have to manually bury the *Messages* buffer because
it's in the way as well when burying buffer 1.  All this is very ugly
but I can't think of a better fix without a rather complete rewrite of
desktop's handling of the buffer lists.

martin
*** lisp/desktop.el	2012-05-13 03:05:06 +0000
--- lisp/desktop.el	2012-05-27 10:52:53 +0000
***************
*** 1020,1025 ****
--- 1020,1037 ----
  			 (format ", %d to restore lazily"
  				 (length desktop-buffer-args-list))
  		       ""))
+ 	    ;; Bury the *Messages* buffer to not reshow it when burying
+ 	    ;; the buffer we switched to above.
+ 	    (when (buffer-live-p (get-buffer "*Messages*"))
+ 	      (bury-buffer "*Messages*"))
+ 	    ;; Clear all windows' previous and next buffers, these have
+ 	    ;; been corrupted by the `switch-to-buffer' calls in
+ 	    ;; `desktop-restore-file-buffer' (bug#1156).  This is a
+ 	    ;; brute force fix and should be replaced by a more subtle
+ 	    ;; strategy eventually.
+ 	    (walk-window-tree (lambda (window)
+ 				(set-window-prev-buffers window nil)
+ 				(set-window-next-buffers window nil)))
  	    t))
        ;; No desktop file found.
        (desktop-clear)