9

I'm looking for a way to add a new full-height window split to an existing (splitted) window configuration. Because I don't know how to explain it properly I'll just post some ASCII graphics showing the desired behaviour for two example window configurations:

             from                              to  

  +-------------------------+      +---------------------+---+  
  |                         |      |                     |   |  
  |                         |      |                     |   |  
  |            A            |  =>  |           A         | E |  
  |                         |      |                     |   |  
  |                         |      |                     |   |  
  +-------------------------+      +---------------------+---+  

  +------------+------------+      +----------+----------+---+  
  |            |     B      |      |          |   B      |   |
  |     A      +------------+      |     A    +----------+   |
  |            |     C      |  =>  |          |   C      | E | 
  +------------+------------+      +----------+----------+   |
  |            D            |      |          D          |   |
  +-------------------------+      +---------------------+---+  

where the function accepts the desired width of the new window E and shrinks the widths of A, B, C, and D accordingly. Edit2: Note that the above two drawings are examples of the expected behaviour for a concrete case. I'm looking for a general function that does this independently of the configuration in the from column (i.e. the number of windows [splits] in the from column should be arbitrary).

I'm also looking for this functionality on the left side and on the top and bottom of a frame.

Edit: From @Nsukami_'s comment I realised that the functionality I'm looking for is a special case of a more abstract problem. So I'll phrase that problem:

How do you store a window configuration (consisting of any number of windows and buffers) and "paste" the stored config into an existing window?

The "paste" should then preserve relative window sizes and the splitting; naturally the resulting pasted config is a scaled copy.

4
  • The first behavior can be obtained by passing the size argument to split-window-right as C-u -width C-x 3. Change the width to whatever you want and note the negative sign.
    – Vamsi
    Oct 1, 2014 at 23:06
  • I'm thinking about pre define some layouts, but not sure.
    – Nsukami _
    Oct 2, 2014 at 0:18
  • @Nsukami_ Is it possible to store a window layout (e.g. the layout of A,B,C, and D) and then insert this layout into a new window? Then my problem could be solved by 1) storing the current window config, 2) changing the layout to show only one window which is then split horizontally [essentially forming the window for E and the placeholder window for the others, lets call it Z], 3) finally insertion of the original layout into the left window (Z)
    – elemakil
    Oct 2, 2014 at 10:00
  • You will have to adjust the layout before insertion as they contain the window sizes as well. Also insertion of a layout into one particular window is not possible without custom elisp AFAIK
    – Vamsi
    Oct 2, 2014 at 17:03

2 Answers 2

5

The following function should do what you want. The trick is to split root window of current frame.

(defun my-split-main-window (direction size)
  "Split the main window in the DIRECTION where DIRECTION is a symbol with
possible values of right, left, above or below and SIZE is the final size of the
windows, if the window is split horizontally (i.e. in DIRECTION below or above)
SIZE is assumed to be the target height otherwise SIZE is assumed to be the
target width"
  (let* ((new-window (split-window (frame-root-window) nil direction))
         (horizontal (member direction '(right left))))
    (save-excursion 
      (select-window new-window)
      (enlarge-window (- size (if horizontal
                                  (window-width)
                                (window-height)))
                      horizontal))
    new-window))

Call the function with direction in which you to split the window and the size of the new window. The above returns the newly created window. The concept and windows and frames are explained very well in the GNU Emacs Lisp Reference Manual.

1
  • Perfect! This is just what I wanted.
    – elemakil
    Oct 5, 2014 at 10:05
0

Not sure if the best solution, as not enough abstracted, I'm actually solving only one use case. The trick is write a function to go from layoutX to layoutY, and another one to go from layoutY to layoutX

(defun from-x-to-y ()
 (interactive)
 (delete-other-windows)
 (split-window-vertically) ;;
 (let ((current-prefix-arg 10)) ;; emulate C-u
   (call-interactively 'enlarge-window) ;; resize
   )
 (split-window-horizontally) ;; -> |
 (next-multiframe-window)
 (split-window-vertically) ;;  -> --
 (previous-multiframe-window)
)

(defun from-y-to-x ()
  (interactive)
  (delete-other-windows)
  (split-window-horizontally) ;; -> |
  (let ((current-prefix-arg -60)) ;; emulate C-u
    (call-interactively 'shrink-window-horizontally) ;; resize
    )
  (split-window-vertically) ;; -> --
  (let ((current-prefix-arg 10)) ;;
    (call-interactively 'enlarge-window) ;;
    )
  (split-window-horizontally) ;;
  (next-multiframe-window)
  (split-window-vertically) 
  (previous-multiframe-window)
)

I hope that solution will help

How do you store a window configuration (consisting of any number of windows and buffers) and "paste" the stored config into an existing window?

Just found a package named layout.el, I've never used it but it seems to be what you're looking for, you'll tell us if ok.

EDIT:

Trying to find a more generic solution, it seems that you can use M-x switch-to-buffer-other-frame to go from a buffer in a frame, let say with a layout X, to another buffer in another frame with a layout Y.

You can also be in a layout X, store this layout in a register C-x r f (frame-configuration-to-register), go to another layout, and when necessary, switch back to the previous one, calling what inside the register with C-x r j (jump-to-register)

2
  • As far as I can tell layout.el does a similar thing as winner: (re)storing the window configuration of the complete frame, not storing the complete config and restoring it into an existing window. The function you wrote on the other hand are indeed not the general solutions I'm looking for. They solve my second example, which was not meant as the concrete problem but only an example. I'm looking for a solution that works in the general case.
    – elemakil
    Oct 2, 2014 at 12:00
  • Still digging, and I think the general solution could be switch-to-buffer-other-frame if 'from' is a frame and 'to' is another frame
    – Nsukami _
    Oct 2, 2014 at 12:45

Your Answer

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

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