2

I'd like to cycle between an active minibuffer window and the last recent buffer.

1  (defun cycle-to-minibuffer-window ()
2    (interactive)
3    (when (active-minibuffer-window)
4      (if (minibuffer-window-active-p (get-buffer-window))
5           (select-window (other-buffer (current-buffer)))
6        (select-window (active-minibuffer-window)))))
7  
8  (global-set-key (kbd "C-<f9>") #'cycle-to-minibuffer-window)

To bad that line 5 (other-buffer (current-buffer)) returns, in this case, the wrong buffer. :(
Which elisp construct could I use instead to get the buffer|window I wanted?

Example (tested with emacs -Q):

  1. There are 3 buffers: *scratch*, *Messages* and *Minibuffer-0*.
  2. My active buffer is *scratch*. I do find-file aka C-x C-f.
  3. Now pressing C-<F9> (calling my function), wants to switch to *Messages* buffer, but *scratch* buffer would be correct.

3 Answers 3

1

If you use Icicles then the buffer you want is the value of variable icicle-pre-minibuffer-buffer. It is the buffer that was current before the minibuffer became active."

If you don't use Icicles then you can save this buffer in a variable yourself by adding a function that sets it to minibuffer-setup-hook. E.g.

(defvar my-pre-minibuffer-buffer nil
  "Buffer that was current before the minibuffer became active.")

(defun my-save-pre-buffer ()
  "Set `my-pre-minibuffer-buffer'."
  (setq my-pre-minibuffer-buffer  (my-last-non-minibuffer-buffer)))

(defun my-last-non-minibuffer-buffer ()
  "Return the most recently used non-minibuffer live buffer."
  (catch 'my-last-non-minibuffer-buffer
    (dolist (buf  (buffer-list))
      (when (and (buffer-live-p buf)  (not (minibufferp buf)))
        (throw 'my-last-non-minibuffer-buffer buf)))
    nil))

(add-hook 'minibuffer-setup-hook 'my-save-pre-buffer)

Having this buffer in a global variable means you can access it anytime. E.g.:

(with-current-buffer my-pre-minibuffer-buffer ...)

or

(pop-to-buffer my-pre-minibuffer-buffer)
1

Another option I've found:

(nth 1 (buffer-list))

The minibuffer will be the 0th one in the buffer-list and the previous buffer is the 1st.

1
  • (select-window (get-buffer-window (nth 1 (buffer-list)))) seems indeed to work
    – jue
    Dec 10, 2021 at 16:03
0

Another solution, which will only work if you use ivy, is to replace line 5 from my question with:

  (select-window (ivy--get-window ivy-last))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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