I would like to open in emacs, with a shortcut/bookmark three files in this configuration:

|       | B |
|   A   |___|
|       | C |

A is my main editing file, B is for the outline of what I write in A and C is for notes. Note that I manually set this layout because the second column is much smaller than what C-x 3 produces.

I'm using lawlist-bookmark -- https://stackoverflow.com/a/19284395/2112489 -- which allows me to use F5 and then a letter shortcut to open quickly a file configured. But with this solution, the opened file take all the space and I have to set manually the layout of emacs to achieve the picture above. I am looking for a solution which will open the three files in the specific geometry layout with one keystroke (after typing F5 to enter inside bookmarks "menu").

Is it possible?

My current bookmarks:

(global-set-key (kbd "<f5>") 'lawlist-bookmark)
(defun lawlist-bookmark (choice)
  "Choices for directories and files."
  (interactive "cf[o]lder | [F]ile | ... )
   ((eq choice ?o)
    (dired "~/folder"))
   ((eq choice ?f)
    (find-file "/~file.tex")
    (message "Opened:  %s" (buffer-name)))
   (t (message "Quit"))))

1 Answer 1


It will be necessary to decide ahead of time what windows/buffers will be A, B and C. The alist argument for the left window-width can be adjusted to taste -- it is presently hard-coded to 70. This example uses an internal function window--display-buffer, which requires some general understanding of certain functions inside window.el. The selected-window is letter B, but this can be changed (with a little coding) if so desired.

(defun example-fn ()
  "To try this example, type:  M-x example-fn"
  (let ((a (dired-noselect "~"))
        (b (find-file-noselect "~/foo.txt"))
        (c (get-buffer-create "*scratch*")))
    (switch-to-buffer b)
    ;; See the doc-strings for `split-window' and `window--display-buffer'.
     a (split-window (selected-window) nil 'left)
     'window '((window-width . 70)) display-buffer-mark-dedicated)
     c (split-window (selected-window) nil 'below)
     'window nil display-buffer-mark-dedicated)))

And, if a keyboard shortcut is desired, it can be set with:

(global-set-key (kbd "<f5>") 'example-fn)

To incorporate this new example into lawlist-bookmark, the entire let section of example-fn can be added or just use the name of the function itself.

(defun lawlist-bookmark (choice)
  "Choices for directories and files.  http://stackoverflow.com/a/19284395/2112489"
  (interactive "c[3]-way | [D]ired | [v]ocab.org | [g]td.org | [d]iary.org | [n]otes.org")
    ((eq choice ?3)
    ((eq choice ?D)
     (dired "/very/long/and/boring/path/which/make/me/use/tab/for/..."))
    ((eq choice ?v)
     (find-file "/Users/HOME/.0.data/vocab.org")
     (message "Opened:  %s" (buffer-name)))
    ((eq choice ?g)
     (find-file "/Users/HOME/.0.data/gtd.org")
     (message "Opened:  %s" (buffer-name)))
    ((eq choice ?d)
     (find-file "/Users/HOME/.0.data/diary.org")
     (message "Opened:  %s" (buffer-name)))
    ((eq choice ?n)
     (find-file "/Users/HOME/.0.data/notes.org")
     (message "Opened:  %s" (buffer-name)))
    (t (message "Quit"))))

Pursuant to the request of the original poster in a comment underneath the initial answer, the following is an example of how to select window letter A:

(defun example-fn-two ()
  "To try this example, type:  M-x example-fn"
  (let ((window-a nil)
        (window-b (selected-window))
        (window-c nil)
        (buffer-a (dired-noselect "~"))
        (buffer-b (find-file-noselect "~/foo.txt"))
        (buffer-c (get-buffer-create "*scratch*")))
    (set-window-buffer window-b buffer-b)
    (setq window-a
           buffer-a (split-window window-b nil 'left)
           'window '((window-width . 70)) display-buffer-mark-dedicated))
    (setq window-c
           buffer-c (split-window window-b nil 'below)
           'window nil display-buffer-mark-dedicated))
    (select-window window-a)))
  • This works still perfectly but I am trying to modify a little detail: the focus is on the last buffer opened (c). How can I put it on buffer a?
    – ppr
    Sep 14, 2017 at 21:24
  • 1
    window--display-buffer returns the WINDOW. You can wrap the last statement that deals with c using (select-window (window--display-buffer c ....)) and that will select window c. The code assumes we wanted b selected, so you might want to use set-window-buffer with the appropriate arguments instead of switch-to-buffer, but you don't have to change that portion if you don't want to.
    – lawlist
    Sep 14, 2017 at 22:31
  • Sorry I was incorrect. The focus is indeed on the buffer b. I would like to have it on buffer a. I tried to change the last part of the code for (select-window (window--display-buffer a (window--display-buffer c (split-window (selected-window) nil 'below) 'window nil display-buffer-mark-dedicated))))). But I have still the focus on b.
    – ppr
    Sep 17, 2017 at 10:05
  • 1
    I have labeled the buffers and windows more distinctively in the new example-fn-two. When we split left and when we spit below, we need to visualize in our own mind that we are in window B. The last line can be changed to suit your needs -- i.e., you can just change the window letter of the last line to any of the three possibilities; or, if you want to select B you could even omit the last line since we were initially in window B to begin with.
    – lawlist
    Sep 17, 2017 at 17:45
  • I tried to adapt this example to open only to files (on the left and the other on the right). I deleted everything related to buffer/window c but I have an error messsage "let: Symbol’s value as variable is void: buffer-b".
    – ppr
    Nov 28, 2017 at 15:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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