From 4cf60c3fea16b60eb18c9a7d8403b75c89aeffef Mon Sep 17 00:00:00 2001 From: Case Duckworth Date: Fri, 21 Oct 2022 21:37:30 -0500 Subject: blhe --- lisp/+window.el | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 lisp/+window.el (limited to 'lisp/+window.el') diff --git a/lisp/+window.el b/lisp/+window.el new file mode 100644 index 0000000..52b3712 --- /dev/null +++ b/lisp/+window.el @@ -0,0 +1,130 @@ +;;; +window.el --- Fixes for Emacs's window.el -*- lexical-binding: t; -*- + +;;; Commentary: + +;; Do I want to propose this change in the Emacs ML? + +;;; Code: + +(require 'window) + +;;; Split windows based on `window-total-width', not `window-width' +;; I have to just redefine these functions because the check is really deep in +;; there. + +(defun window-splittable-p (window &optional horizontal) + "Return non-nil if `split-window-sensibly' may split WINDOW. +Optional argument HORIZONTAL nil or omitted means check whether +`split-window-sensibly' may split WINDOW vertically. HORIZONTAL +non-nil means check whether WINDOW may be split horizontally. + +WINDOW may be split vertically when the following conditions +hold: +- `window-size-fixed' is either nil or equals `width' for the + buffer of WINDOW. +- `split-height-threshold' is an integer and WINDOW is at least as + high as `split-height-threshold'. +- When WINDOW is split evenly, the emanating windows are at least + `window-min-height' lines tall and can accommodate at least one + line plus - if WINDOW has one - a mode line. + +WINDOW may be split horizontally when the following conditions +hold: +- `window-size-fixed' is either nil or equals `height' for the + buffer of WINDOW. +- `split-width-threshold' is an integer and WINDOW is at least as + wide as `split-width-threshold'. +- When WINDOW is split evenly, the emanating windows are at least + `window-min-width' or two (whichever is larger) columns wide." + (when (and (window-live-p window) + (not (window-parameter window 'window-side))) + (with-current-buffer (window-buffer window) + (if horizontal + ;; A window can be split horizontally when its width is not + ;; fixed, it is at least `split-width-threshold' columns wide + ;; and at least twice as wide as `window-min-width' and 2 (the + ;; latter value is hardcoded). + (and (memq window-size-fixed '(nil height)) + ;; Testing `window-full-width-p' here hardly makes any + ;; sense nowadays. This can be done more intuitively by + ;; setting up `split-width-threshold' appropriately. + (numberp split-width-threshold) + (>= (window-total-width window) + (max split-width-threshold + (* 2 (max window-min-width 2))))) + ;; A window can be split vertically when its height is not + ;; fixed, it is at least `split-height-threshold' lines high, + ;; and it is at least twice as high as `window-min-height' and 2 + ;; if it has a mode line or 1. + (and (memq window-size-fixed '(nil width)) + (numberp split-height-threshold) + (>= (window-height window) + (max split-height-threshold + (* 2 (max window-min-height + (if mode-line-format 2 1)))))))))) + +(defun split-window-sensibly (&optional window) + "Split WINDOW in a way suitable for `display-buffer'. +WINDOW defaults to the currently selected window. +If `split-height-threshold' specifies an integer, WINDOW is at +least `split-height-threshold' lines tall and can be split +vertically, split WINDOW into two windows one above the other and +return the lower window. Otherwise, if `split-width-threshold' +specifies an integer, WINDOW is at least `split-width-threshold' +columns wide and can be split horizontally, split WINDOW into two +windows side by side and return the window on the right. If this +can't be done either and WINDOW is the only window on its frame, +try to split WINDOW vertically disregarding any value specified +by `split-height-threshold'. If that succeeds, return the lower +window. Return nil otherwise. + +By default `display-buffer' routines call this function to split +the largest or least recently used window. To change the default +customize the option `split-window-preferred-function'. + +You can enforce this function to not split WINDOW horizontally, +by setting (or binding) the variable `split-width-threshold' to +nil. If, in addition, you set `split-height-threshold' to zero, +chances increase that this function does split WINDOW vertically. + +In order to not split WINDOW vertically, set (or bind) the +variable `split-height-threshold' to nil. Additionally, you can +set `split-width-threshold' to zero to make a horizontal split +more likely to occur. + +Have a look at the function `window-splittable-p' if you want to +know how `split-window-sensibly' determines whether WINDOW can be +split." + (let ((window (or window (selected-window)))) + (or (and (window-splittable-p window) + ;; Split window vertically. + (with-selected-window window + (split-window-below))) + (and (window-splittable-p window t) + ;; Split window horizontally. + (with-selected-window window + (split-window-right))) + (and + ;; If WINDOW is the only usable window on its frame (it is + ;; the only one or, not being the only one, all the other + ;; ones are dedicated) and is not the minibuffer window, try + ;; to split it vertically disregarding the value of + ;; `split-height-threshold'. + (let ((frame (window-frame window))) + (or + (eq window (frame-root-window frame)) + (catch 'done + (walk-window-tree (lambda (w) + (unless (or (eq w window) + (window-dedicated-p w)) + (throw 'done nil))) + frame nil 'nomini) + t))) + (not (window-minibuffer-p window)) + (let ((split-height-threshold 0)) + (when (window-splittable-p window) + (with-selected-window window + (split-window-below)))))))) + +(provide '+window) +;;; +window.el ends here -- cgit 1.4.1-21-gabe81