Do frames in emacs have a handle the way buffers do? In particular, can I specify that a particular file should be opened in a specified frame? I would like to have two frames where I use one for development and use the other to read documentation and browse tags.

(Tagging the question with emacsclient and linux because I am ok with an answer which requires them.)


You can customize display-buffer-alist to achieve what you want, you can read more about the variable by doing C-hvdisplay-buffer-alistRET. Basically this variable allows you to register custom functions to display certain buffers. Below if a non-generic solution to your question. I have assumed certain things, you might want to adopt it your workflow, the assumptions are the buffer containing your documentation match the regexp Help, and you want to display them in a dedicated frame Help.

(defun my-show-doc-in-frame (buffer options)
  ;; Get the frame named 'Help' or create one if such a frame does not exist
  (let ((help-frame (select-frame (or (cdr (assoc-string "Help" (make-frame-names-alist)))
                                      (make-frame '((name . "Help")))))))
    ;; This assumes you want to display just one window in the dedicated frame
    (set-window-buffer (car (window-list help-frame))  buffer nil)))

(add-to-list 'display-buffer-alist (cons "Help" (cons #'my-show-doc-in-frame nil)))

Now if you do C-hvdisplay-buffer-alistRET, the documentation will appear in a frame called 'Help'


I think you may want your opened frame in control. If you make certain files automatically opened in another frames, then when you open more than one it will create many frames that becomes unmanageable and defeats your purpose.

Since you use Helm and if you use any Helm Projectile command or helm-find-files or helm-mini... (Helm commands that are related to files), C-c C-o opens the selected files/buffers in another frames.

For vanilla Emacs solution, anything prefixed with C-x 5 opens file/buffer in another frame.

But you can use another method to achieve your purpose. You can use package like workgroup to manage your window configurations. What workgroup does is allows you to create workspaces, each workspace holds a window configuration with its buffers and you can switch between window configurations easily and persist the workspaces across Emacs sessions. Of course, you can use it along with frame as well, i.e. each frame holds a workspace. Here is my configuration:

(setq wg-prefix-key (kbd "C-c v"))
(setq wg-morph-on nil    ; disable switching animation
      wg-no-confirm t    ; don't ask for confirmation
      wg-file (concat user-emacs-directory "workgroups") ; save your workspaces in ~/.emacs.d/wokgroups for future sessions
      wg-switch-on-load nil ; don't switch to first workgroup when it is loaded

(global-set-key (kbd "C-c c") 'wg-create-workgroup)
(global-set-key (kbd "C-c b") 'wg-switch-to-workgroup)

(require 'workgroups)
(workgroups-mode 1)

Why did I choose such key bindings? Because the three keys are close together. C-c c and C-c b should be frequently used commands when you use workgroups, and C-c v is for everything else. And the three are close with each other on the keyboard, which makes it easy to remember and fast to work with workgroups: c v b.

Now, let's try create a workgroup with C-c c. Create 3 or 4 windows t hat hold something.

Then, create another workgroup with C-c c. Also create 3 or 4 windows t hat hold something.

Now you can switch back and forth with C-c v a between current and previous workgroups. If you want to go next/previous workgroup, use C-c v n and C-c v p.

Basically, workgroups is the same as how Emacs handles frames in terminal, which I think is the missing feature in GUI Emacs that I was always wishing for.

If you have more than 2 workgroups and want to select one deterministically, press C-c b. Since you use Helm, you get a nice and visible list of workgroups.

To persist your workgroups between session, you can use C-c v S to save all your workgroups into the wg-file you defined earlier. You can restore it later with C-c v C-l, or automatically when your Emacs starts:

(defun wg-load-default ()
  "Run `wg-load' on `wg-file'."
  (when (file-exists-p wg-file)
    (wg-load wg-file)))

Finally, to navigate frame easier, you can select frame by name with select-frame-by-name command. I bound it to C-x 5 s

(global-set-key (kbd "C-x 5 s") 'select-frame-by-name)

Again, it gives you a nice visible list with Helm.

You can cycle between frames with C-x 5 o, similar to how you cycle windows.

  • Thanks for yet another great answer! I have accepted Iqbal's answer since it solved the particular problem that I was interested in. Will take a look at workgroups and your setup. – Pradhan Dec 26 '14 at 19:42

I think it's a bit of wasted effort of trying to make this arrangement, i.e. docs in one frame and code in the other. This is because all Emacs frames share the buffers anyway, so all your arranging comes to naught with a single ido-switch-buffer.

But when that happens, ace-window can help you restore the balance. Either C-u ace-window, or a plain ace-swap-window can swap the windows on separate frames.

  • It is convenient when you have each frame with its own window configuration. For example, you can have a frame hold 4 windows contains only relevant documents and another contains only related code buffers. Switching buffers will mess your window configuration that are complex to recreate. You can use registers to save window configurations, but it's not as convenient when you have two monitors to hold two frames. – Tu Do Dec 26 '14 at 11:02
  • Wow, that's really elaborate. Now I feel like a peasant with my one-frame, one-window most of the time:). But at least my workflow isn't hampered when I switch from my work machine to this tiny 13-inch laptop. – abo-abo Dec 26 '14 at 11:14
  • Frame-Bufs utilizes a custom buffer-list that is stored in the frame-parameter of each frame, and this is one method of keeping the buffers associated with a particular frame. I configured Tabbar to use it and I can switch between associated and non-associated tab groups on a per frame basis. Each of my approximately six (6) frames are full screen, unless I have reduced them so that I can see other programs simultaneously. I switch between frames with a custom function that pulls up a minibuffer list of numbers/letters and the names of the frames to choose from. I use desktop and laptop. – lawlist Dec 26 '14 at 15:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.