I use tiling window manager and usually prefer it to handle emacs frames instead of using emacs windows. Is there a way I could force emacs to spawn new buffers in new frames automatically? Ideally this behavior should be toggled via some command.
2 Answers
C-h v pop-up-frames
tells you this. It should get you much of the way there.
pop-up-frames
is a variable defined inwindow.el
.Its value is
t
Original value was
nil
Documentation:
Whether `display-buffer' should make a separate frame.
If
nil
, never make a separate frame.If the value is
graphic-only
, make a separate frame on graphic displays only.Any other non-
nil
value means always make a separate frame.You can customize this variable.
This, and its linked pages, might also help, at least by describing some of the problems of trying to use frames-only by default.
pop-up-frames
certainly does the trick but it is too awkward to use. It will spawn everything in new frame.
Much finer control may be reached by using display-buffer-alist
. It allows conditionally opening buffers in new frames.
I wrote a small minor mode pop-up-frames-mode
using display-buffer-alist
method:
;; https://stackoverflow.com/a/1511827/5745120
(defun which-active-modes ()
"Which minor modes are enabled in the current buffer."
(let ((active-modes))
(mapc (lambda (mode) (condition-case nil
(if (and (symbolp mode) (symbol-value mode))
(add-to-list 'active-modes mode))
(error nil) ))
minor-mode-list)
active-modes))
(defun pop-up-frames-switch-to-buffer (buffer alist)
"Pop up frames switch to buffer command."
(member 'pop-up-frames-mode (which-active-modes)))
(setq display-buffer-alist
(append display-buffer-alist
'((pop-up-frames-switch-to-buffer . ((display-buffer-reuse-window display-buffer-pop-up-frame) . ((reusable-frames . 0)))
))))
(define-minor-mode pop-up-frames-mode
"Pop up frames minor mode"
:lighter " PUF")
(provide 'pop-up-frames-mode)
It spawns new frame only when pop-up-frames-mode
is enabled in current buffer and does not create duplicate windows.