Subject: bug#71616: switch-to-buffer behaves inconsistently when switch-to-buffer-obey-display-actions is t and nil .

From: Juri Linkov <[email-masked]>
Date: Mon, 17 Jun 2024 21:34:18 +0300

> Recently I found a strange behavior about `switch-to-buffer' when
> `switch-to-buffer-obey-display-actions' is t.
>
> At the moment, by default, `switch-to-buffer-obey-display-actions' is set
> as nil, so `switch-to-buffer' does not be affected by some display-buffer
> options, such as `display-buffer-overriding-action',
> `display-buffer-alist', etc.
>
> However, if `switch-to-buffer-obey-display-actions' is t, 
> `switch-to-buffer' can adapt these display-buffer options. This feature was
> introduced by the commit 3f36651c6470bab951f12f486eb4928235f1ba50 and the
> implementation is to call `pop-to-buffer-same-window' inside
> `switch-to-buffer'.
>
> More details, see 
> bug#32790
> https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=3f36651c6470bab951f12f486eb4928235f1ba50
>
> https://mail.gnu.org/archive/html/bug-gnu-emacs/2018-11/msg00962.html
>
> The problem is that the `switch-to-buffer' also obeys
> `switch-to-buffer-preserve-window-point' while `pop-to-buffer-same-window'
> doesn't. Therefore this new feature has to be compatible with
> `switch-to-buffer-preserve-window-point' too. This has been implemented in
> that commit but not quite right IMHO.
>
> Let's examine the different behaviors when
> `switch-to-buffer-obey-display-actions' is nil and t in `switch-to-buffer':
>
> - When `switch-to-buffer-obey-display-actions' is nil,
> `switch-to-buffer-preserve-window-point' is t (or nil, no matter actually)
> and `(eq buffer (window-buffer))`, the `switch-to-buffer' will do nothing.
>
> - When `switch-to-buffer-obey-display-actions' is t and
> `switch-to-buffer-preserve-window-point' is t, `switch-to-buffer' will set
> window-point if the target window is the same as the current window (yep,
> that is the switch semantics). However, it does not consider what happens
> when the target buffer is the same as the current buffer, just like `(eq
> buffer (window-buffer))` in the 1st situation!
>
> BTW the `switch-to-buffer-preserve-window-point' docs is a bit confusion:
>
>> This variable is ignored if the buffer is already displayed in
>> the selected window or never appeared in it before, or if
>> ‘switch-to-buffer’ calls ‘pop-to-buffer’ to display the buffer,
>> or non-nil ‘switch-to-buffer-obey-display-actions’ displays it
>> in another window.
>
> It doesn't mention what happens if non-nil
> ‘switch-to-buffer-obey-display-actions’ displays it in the same window with
> the buffer that is already displayed. I also don't know whether the
> sentence i.e. "if the buffer is already displayed in the selected window"
> includes ‘switch-to-buffer-obey-display-actions’ is t.
>
> The following are the minimal steps to reproduce.
>
> ## Test with default settings:
> 1. Emacs -Q
> 2. Open a .el file, e.g. window.el, and keep the cursor location at 1
> 3. Click buffers menu -> *scratch* to switch buffer
> 4. Click buffers menu -> window.el to switch buffer back
> 5. Move the current location to L24
> 6. M-x switch-to-buffer window.el
>
> The result is that the buffer and window state keeps original, everything
> is fine.
>
> ## Test with switch-to-buffer-obey-display-actions = t
> 1. Emacs -Q
> 2. M-x eval-expression (setq switch-to-buffer-obey-display-actions t)
> 2. Open a .el file, e.g. window.el, and keep the cursor location at 1
> 3. Click buffers menu -> *scratch* to switch buffer
> 4. Click buffers menu -> window.el to switch buffer back
> 5. Move the current location to L24
> 6. M-x switch-to-buffer window.el 
> The result is that the current cursor location jumps to location at 1!
> This inconsistent behavior convinced me that this is a bug.

I confirm this in Emacs 30.  Maybe Martin could suggest how to fix this.