Last year I blogged about a solution to a common problem I had with windows in Emacs. I wanted to be able to exit particular fullframed buffers and restore the windows as they were before opening those buffers.

The core of my solution is the following function:

(defun mu-save-wins-then-call (func &optional args)
"Save current window configuration, then call FUNC optionally with ARGS."
(interactive)
(push (current-window-configuration) mu-saved-window-configuration)
(cond
;; We have arguments for the function
((bound-and-true-p args) (funcall func args))
;; The function requires exactly one argument, and we want it to be nil
((equal args "nil") (funcall func nil))
;; The function does not expect arguments
(t (funcall func))))


This function works fine for most of my cases, but it doesn’t take the prefix argument into account. Since I rely heavily on shell-mode, at times I need to open more than one shell buffer, and the documentation of the shell command specifies that the prefix argument can be used to open new buffers on demand:

Run an inferior shell, with I/O through BUFFER (which defaults to shell'). Interactively, a prefix arg means to prompt for BUFFER.

Hence, I need to mimic C-u M-x shell in mu-save-wins-then-call:

(defun mu-save-wins-then-call (func &optional args)
"Save current window configuration, then call FUNC optionally with ARGS."
(interactive "P")
(push (current-window-configuration) mu--saved-window-configuration)
(cond
;; We have the prefix argument
((= (prefix-numeric-value args) 4)
(let ((current-prefix-arg 4))
(call-interactively func)))
;; We have arguments for the function
((or (bound-and-true-p args)
(stringp args))
(funcall func args))
;; The function does not expect arguments
(t (funcall func))))


Now I can open as many fullframed shell buffers as I want with C-u F1:

(defun mu-shell-open (&optional new-buffer)
"Save window configuration and call shell'.
With NEW-BUFFER open a new buffer."
(interactive "P")
(mu-save-wins-then-call #'shell new-buffer))


Note that mu-pop-window-configuration is detailed here.