0

I am looking for a command that would switch to the buffer I most recently selected in the current window. The command mode-line-other-buffer will switch to the most recently selected buffer not displayed in any window, regardless of whether it was selected in the current window or in some other window.

For illustration, suppose I have two open windows, 1 and 2, and four open buffers, A, B, C, D. Buffer A is displayed in window 1, and buffer C is displayed in window 2. Now suppose that,

  • with point on A,
  • I first switch to B, then
  • select window 2, then
  • switch to D, and finally
  • select window 1.

At that point, the command mode-line-other-buffer, if invoked, will switch to C. I would like an alternative command that, if invoked, would switch to A instead. Moreover, repeated invocations of this alternative command should toggle between B and A (just like repeated invocations of mode-line-other-buffer toggle between B and C), since either of these buffers becomes the most recently selected buffer when the other buffer is selected.

1
1

The function you are looking for is previous-buffer.

Its doc string says:

Call ‘switch-to-prev-buffer’ unless the selected window is the
minibuffer window or is dedicated to its buffer.

The referenced function switch-to-prev-buffer is mentioned on the info page for Window History:

– Command: switch-to-prev-buffer &optional window bury-or-kill
This command displays the previous buffer in WINDOW. The argument
WINDOW should be a live window or ‘nil’ (meaning the selected
window). If the optional argument BURY-OR-KILL is non-‘nil’, this
means that the buffer currently shown in WINDOW is about to be
buried or killed and consequently should not be switched to in
future invocations of this command.

The previous buffer is usually the buffer shown before the buffer
currently shown in WINDOW. However, a buffer that has been buried
or killed, or has been already shown by a recent invocation of
‘switch-to-prev-buffer’, does not qualify as previous buffer.

If repeated invocations of this command have already shown all
buffers previously shown in WINDOW, further invocations will show
buffers from the buffer list of the frame WINDOW appears on (*note
Buffer List::), trying to skip buffers that are already shown in
another window on that frame.

1
  • Thank you for your answer. Unfortunately, while previous-buffer does switch to A in my example, a second invocation of it switches to C, not to B, despite the latter being the most recently selected buffer. I have appended a sentence to my question that clarifies this point.
    – Pablo
    May 11 at 11:18
0

Although I'm not a Spacemacs user, I found that Spacemacs has a command that does exactly what I described:

(defun spacemacs/alternate-buffer (&optional window)
  "Switch back and forth between current and last buffer in the
current window."
  (interactive)
  (let ((current-buffer (window-buffer window))
        (buffer-predicate
         (frame-parameter (window-frame window) 'buffer-predicate)))
    ;; switch to first buffer previously shown in this window that matches
    ;; frame-parameter `buffer-predicate'
    (switch-to-buffer
     (or (cl-find-if (lambda (buffer)
                       (and (not (eq buffer current-buffer))
                            (or (null buffer-predicate)
                                (funcall buffer-predicate buffer))))
                     (mapcar #'car (window-prev-buffers window)))
         ;; `other-buffer' honors `buffer-predicate' so no need to filter
         (other-buffer current-buffer t)))))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.