help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Making the width of three windows equal


From: Pascal Bourguignon
Subject: Re: Making the width of three windows equal
Date: Wed, 03 Aug 2005 05:11:49 +0200
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.0.50 (gnu/linux)

"Samuel" <knipknap@gmail.com> writes:

> Pascal Bourguignon wrote:
>> > When opening multiple (three) vertically split windows by pressing C-x 3
>> > twice, one of the windows takes up 50% of the screen width and the other
>> > two 25% each. I am looking for an equivalent to what C-x + does for
>> > horizontally split windows, that is, making each of them take up 33% of
>> > the terminal width. Is there a shortcut to do this?
>>
>> Since balance-windows doesn't work vertically (or is it
>> horizontally?), your best bet is to fetch its sources and to edit them
>> to implement horizontal (or is it vertical?) window balancing.
>
> Thanks, Pascal.
> (I had a look at the balance-windows source now, but geesh, this
> language is just out of my range.)

Well, even if you don't understand anything to lisp, it's quite easy
to substitute width for height, left for bottom and right for top,
isn't it?


(defun horizontal-offset ()
  "Number of columns taken by the fringe and vertical scroll bar"
  ;; TODO: Implement in function of the effective fringe and vertical scroll 
bar.
  5)

(defun balance-windows-vertically ()
  "Make all visible windows the same width (approximately)."
  (interactive)
  (let ((count -1) levels newsizes level-size
        (last-window (previous-window (frame-first-window (selected-frame))))
        ;; Don't count the columns that are past the lowest main window.
        total)
    ;; Rightmost edge of last window determines what size we have to work with.
    (setq total
          (+ (window-width last-window) (horizontal-offset)
             (nth 0 (window-edges last-window))))
    ;; Find all the different hpos's at which windows start,
    ;; then count them.  But ignore levels that differ by only 1.
    (let (lefts (prev-left -2))
      (walk-windows (function (lambda (w)
                      (setq lefts (cons (nth 0 (window-edges w))
                                        lefts))))
                    'nomini)
      (setq lefts (sort lefts '<))
      (while lefts
        (if (> (car lefts) (1+ prev-left))
            (setq prev-left (car lefts)
                  count (1+ count)))
        (setq levels (cons (cons (car lefts) count) levels))
        (setq lefts (cdr lefts)))
      (setq count (1+ count)))
    ;; Subdivide the frame into desired number of vertical levels.
    (setq level-size (/ total count))
      (message "levels=%S" levels)
      (message "level-size=%S" level-size)
    (save-selected-window
      ;; Set up NEWSIZES to map windows to their desired sizes.
      ;; If a window ends at the rightmost level, don't include
      ;; it in NEWSIZES.  Those windows get the right sizes
      ;; by adjusting the ones above them.
      (walk-windows (function
                     (lambda (w)
                      (let ((newleft (cdr (assq (nth 0 (window-edges w))
                                                levels)))
                            (newright (cdr (assq (+ (window-width w)
                                                    (horizontal-offset)
                                                    (nth 0 (window-edges w)))
                                                 levels))))
                        (message "newleft=%S newright=%S" newleft newright)
                        (if newright
                            (setq newsizes
                                  (cons (cons w (* level-size (- newright 
newleft)))
                                        newsizes))))))
                    'nomini)
      (message "newsizes=%S" newsizes)
      ;; Make walk-windows start with the leftmost window.
      (select-window (previous-window (frame-first-window (selected-frame))))
      (let (done (count 0))
        ;; Give each window its precomputed size, or at least try.
        ;; Keep trying until they all get the intended sizes,
        ;; but not more than 3 times (to prevent infinite loop).
        (while (and (not done) (< count 3))
          (setq done t)
          (setq count (1+ count))
          (walk-windows (function (lambda (w)
                          (select-window w)
                          (let ((newsize (cdr (assq w newsizes))))
                            (when newsize
                              (enlarge-window (- newsize
                                                 (horizontal-offset)
                                                 (window-width))
                                              t t)
                              (unless (= (window-width)
                                         (- newsize (horizontal-offset)))
                                (setq done nil))))))
                        'nomini))))))

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
Cats meow out of angst
"Thumbs! If only we had thumbs!
We could break so much!"


reply via email to

[Prev in Thread] Current Thread [Next in Thread]