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
raise-frame. Please feel free to substitute
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."
(dolist (the-frame (frame-list))
(when (not (get-buffer-window buffer the-frame))
(setq target-frame 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))