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))
(with-eval-after-load 'shell
(fullframe shell mu-pop-window-configuration))
(bind-key "<f1>" mu-shell-open)
mu-pop-window-configuration
is detailed over at Restoring the window
configuration in Emacs.