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)))
display-buffer-alist
to display buffers in select frames and select windows within those frames. For an example of how this works, check out the answer in this related thread entitled "How to intercept a file before it opens and decide which frame": stackoverflow.com/questions/18346785/… As you may already know, thebuffer-list
for each frame cannot be relied upon as a method for associating buffers with a frame. You may be interested inframe-bufs
by Alp Aker to associate buffers.