Hi,
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=3f36651c6470bab951f12f486eb4928235f1ba50https://mail.gnu.org/archive/html/bug-gnu-emacs/2018-11/msg00962.htmlThe 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.
Emacs 29.3 on Window.
Thanks.
Best regards,
Siyuan Chen