tags:

views:

277

answers:

3

Is there an Emacs equivalent of Vim's C-w _? This command "maximizes" the current window by making it as tall as possible (thus shrinking all of the other windows to be as small as possible).

Importantly, in Vim the other windows don't disappear when you enlarge the current window too far. Instead the current window stops enlarging so that the other windows can continue to live.

In Emacs, windows disappear when they shrink below window-min-height lines. This is annoying. Instead I want the other windows to shrink to window-min-height lines high, and then stop shrinking so they don't go away. Then I could just do (enlarge-window 1000). However I can't figure out how to get this to work.

I'm open to other strategies for maximizing windows if the above isn't possible.

A: 

I don't know the answer you have asked for.

As an alternate workflow, are you away that the open buffers are available with switch-to-buffer (bound to C-x b by default) and that if you tab at this point you'll get a list to choose from?

So I just use delete-other-windows (bound to C-x 1 by default), and use switch-to-buffer to go back.

dmckee
+1  A: 

In my opinion that's a little bit odd behavior, but this should get you started:

edit: filtering out windows which line up on either side, per comments:

(defun maximize-window ()
  (interactive)
  (let* ((lpos (first (window-edges)))
         (rpos (third (window-edges)))
         (in-same-column-p
          (lambda (w) (or (= lpos (first (window-edges w)))
                          (= rpos (third (window-edges w))))))
         (other-windows (remove-if-not in-same-column-p
                                       (rest (window-list))))
         (other-heights (* (length other-windows) window-min-height))
         (my-height (- (frame-height) other-heights)))
    (setf (window-height) (- my-height 1))))
Steven Huwig
This is very close, but if I split my windows horizontally, it counts windows that it shouldn't. Is there a way to get a count of all the windows above or below the current one?
Brian Carper
Just filter them out.
Steven Huwig
This still doesn't work if I have two windows split horizontally above a full-width window on the bottom and try to maximize from the top-right one. It kills the bottom window. But I think I can fix it from here, thanks.
Brian Carper
The problem is that a window will steal height from a neighbor if they're in the same "branch" of a higher level split. Imagine this sequence: C-x 2 C-x 3 C-x 2. Growing the upper right window will first cause the window below it to disappear before its height begins to affect the height of the bottom-most window. So, to truly solve this, you need to both grow the desired window, and shrink others (not that my solution works either). But bonus points for (setf (window-height) ...), that was a new one.
Trey Jackson
fixed the answer to handle Trey Jackson's case
Steven Huwig
+1  A: 

Here's my shot at it. It seems to work pretty well for window configurations of up to 5 windows. But has gotten confused when I had 12 up (most windows pointing to the same buffer). So, it should work for you unless you've got crazy window configurations:

Note: It shrinks windows to the minimum size as specified by the variables window-min-width and window-min-height, which may be more than the actual minimum.

(defun my-maximize-current-window ()
  "Maximize the current window"
  (interactive)
  (my-shrink-all-but-window-in-tree (get-buffer-window (current-buffer)) (car (window-tree))))

(defun my-shrink-all-but-window-in-tree (window tree)
  (if (windowp tree)
      (when (eq tree window) tree)
    (let* ((left (my-shrink-all-but-window-in-tree window (caddr tree)))
           (right (my-shrink-all-but-window-in-tree window (cadddr tree)))
           (vertical (car tree))
           (found (or left right)))
      (my-shrink-windows (not vertical) (if right (caddr tree) (cadddr tree)))
      (select-window window)
      (when found (cons tree found)))))

(defun my-shrink-windows (vertical treetoshrink)
  (if (windowp treetoshrink)
      (let ((size (if vertical
                      (min 0  (- window-min-width (window-width treetoshrink)))
                    (min 0  (- window-min-height (window-height treetoshrink))))))

        (select-window treetoshrink nil)
        (enlarge-window size
                        vertical))
    (my-shrink-windows vertical (caddr treetoshrink))
    (my-shrink-windows vertical (cadddr treetoshrink))))
Trey Jackson
This code doesn't work for all window configurations b/c it mistakenly assumes that the tree simply has a left/right, when in fact there can be any number of windows at a given level of a window tree. I've another version which takes that into account, but you can't (easily) solve this by shrinking windows because they steal from each other and don't always end up *growing* the window you want. So, take it for what you will. I'm not seeing the easy answer.
Trey Jackson