Here is an example using the display-buffer
family of functions, based upon a more complicated example: https://stackoverflow.com/questions/18346785/how-to-intercept-a-file-before-it-opens-and-decide-which-frame . As stated in that related thread, there are several different ways to do this, including, but not limited to let-binding the display-buffer-alist
. In this example, we just use the function my-frame-fn
in the second argument to display-buffer
. We can of course get fancy by examining all of the frame names and add a consecutive numeric digit to the frame name; or, not change the frame name at all; or ... the sky is the limit. We can also add additional frame parameters to place the top / left coordinates wherever we want. We can also adjust the frame size upon frame creation including pixelwise (https://emacs.stackexchange.com/a/17354/2287), or after the fact (https://www.gnu.org/software/emacs/manual/html_node/elisp/Size-and-Position.html). And, we could always programmatically set/select the original frame/buffer instead of the new one if we wanted to ....
I do not like to use select-frame-set-input-focus
in my setup because it will cause frames on OSX to acquire focus and steal away focus from another program that I might be using; e.g., in the case of a long running Emacs function. So, instead I use the combination of select-frame
and raise-frame
. Please feel free to substitute select-frame
for select-frame-set-input-focus
and remove raise-frame
if that is needed for your OS or you simply prefer it like that.
USAGE (1 of 2): (display-buffer (current-buffer) '(my-frame-fn))
USAGE (2 of 2): (display-buffer (find-file-noselect FILENAME) '(my-frame-fn))
(defun my-frame-fn (buffer alist)
"Display the incoming BUFFER in a frame that does not already display it.
Use up the existing frames first, before deciding to create a new frame."
(let (target-frame)
(catch 'break
(dolist (the-frame (frame-list))
(when (not (get-buffer-window buffer the-frame))
(throw 'break
(progn
(setq target-frame the-frame)
(modify-frame-parameters the-frame
(list (cons 'name "OLD"))))))))
(when (null target-frame)
(setq target-frame (make-frame (list (cons 'name "NEW")))))
(select-frame target-frame 'norecord)
(set-window-buffer (get-largest-window) buffer)
(select-window (get-buffer-window buffer))
(raise-frame target-frame)))