From 8c12629f8c4c8726b7b74ad3912abd9cd1cade9c Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Sun, 10 May 2026 15:31:27 -0500 Subject: refactor(cj-window-geometry): rename to cj-window-geometry-lib Same naming-convention fix as the other library renames in this series. Rename modules/cj-window-geometry.el -> modules/cj-window-geometry-lib.el and tests/test-cj-window-geometry.el -> tests/test-cj-window-geometry-lib.el. Update provide forms, file headers, and the (require 'cj-window-geometry) call sites in cj-window-toggle-lib.el, ai-vterm.el, vterm-config.el, and the test file. No behavior change. --- modules/ai-vterm.el | 2 +- modules/cj-window-geometry-lib.el | 81 +++++++++++++++++++++++++++ modules/cj-window-geometry.el | 81 --------------------------- modules/cj-window-toggle-lib.el | 4 +- modules/vterm-config.el | 2 +- tests/test-cj-window-geometry-lib.el | 103 +++++++++++++++++++++++++++++++++++ tests/test-cj-window-geometry.el | 103 ----------------------------------- 7 files changed, 188 insertions(+), 188 deletions(-) create mode 100644 modules/cj-window-geometry-lib.el delete mode 100644 modules/cj-window-geometry.el create mode 100644 tests/test-cj-window-geometry-lib.el delete mode 100644 tests/test-cj-window-geometry.el diff --git a/modules/ai-vterm.el b/modules/ai-vterm.el index 7181c227e..b657b249e 100644 --- a/modules/ai-vterm.el +++ b/modules/ai-vterm.el @@ -36,7 +36,7 @@ (require 'cl-lib) (require 'seq) -(require 'cj-window-geometry) +(require 'cj-window-geometry-lib) (require 'cj-window-toggle-lib) (declare-function vterm "vterm" (&optional buffer-name)) diff --git a/modules/cj-window-geometry-lib.el b/modules/cj-window-geometry-lib.el new file mode 100644 index 000000000..a674a0729 --- /dev/null +++ b/modules/cj-window-geometry-lib.el @@ -0,0 +1,81 @@ +;;; cj-window-geometry-lib.el --- Pure window-geometry helpers -*- lexical-binding: t; -*- + +;; Author: Craig Jennings + +;;; Commentary: + +;; Pure helpers for classifying a window's position in its frame and +;; computing body sizes. Shared between `ai-vterm.el' (F9 dispatch) +;; and `vterm-config.el' (F12 dispatch); the geometry- +;; preservation pattern in both modules captures direction + body +;; size at toggle-off and replays them on the next toggle-on. +;; +;; All functions are pure: they read window/frame edges and return +;; classifications. No side effects, no state. Consumers wrap them +;; with consumer-specific state vars and display logic. + +;;; Code: + +(defun cj/window-direction (window &optional default) + "Return the side WINDOW occupies in its frame. + +Returns one of right, below, left, above. Falls back to DEFAULT +(or right when DEFAULT is nil) when WINDOW fills its frame's +root area. Comparison uses `frame-root-window' edges so the +minibuffer doesn't make every full-area window look like it +fails to span the full height." + (let* ((root (frame-root-window (window-frame window))) + (edges (window-edges window)) + (root-edges (window-edges root)) + (left (nth 0 edges)) + (top (nth 1 edges)) + (right (nth 2 edges)) + (bottom (nth 3 edges)) + (root-left (nth 0 root-edges)) + (root-top (nth 1 root-edges)) + (root-right (nth 2 root-edges)) + (root-bottom (nth 3 root-edges)) + (spans-full-width (and (= left root-left) (= right root-right))) + (spans-full-height (and (= top root-top) (= bottom root-bottom)))) + (cond + ((not spans-full-width) (if (= left root-left) 'left 'right)) + ((not spans-full-height) (if (= top root-top) 'above 'below)) + (t (or default 'right))))) + +(defun cj/window-body-size (window direction) + "Return WINDOW's body size on the axis matching DIRECTION. + +Returns body-width (columns) when DIRECTION is right or left. +Returns body-height (lines) when DIRECTION is below or above. + +Body size, not total size, is the right thing to capture for +geometry replay: total-width includes the right-side divider when +the window has a right sibling but excludes it at the frame edge, +so a captured rightmost window replayed into a middle position +would leave the body 1 col short. Body size is divider- +independent and matches what the user actually sees." + (if (memq direction '(right left)) + (window-body-width window) + (window-body-height window))) + +(defun cj/cardinal-to-edge-direction (direction) + "Map cardinal DIRECTION to its `display-buffer-in-direction' edge variant. + +Returns rightmost/leftmost/bottom/top for right/left/below/above +respectively. Returns nil for any other input. + +The edge variants route splits relative to the frame's main +window rather than the selected window, so a toggle-on lands at +the same frame edge regardless of which window is selected. The +cardinal variants would split the selected window's tree branch +instead, putting the new window mid-frame in multi-window +layouts." + (pcase direction + ('right 'rightmost) + ('left 'leftmost) + ('below 'bottom) + ('above 'top) + (_ nil))) + +(provide 'cj-window-geometry-lib) +;;; cj-window-geometry-lib.el ends here diff --git a/modules/cj-window-geometry.el b/modules/cj-window-geometry.el deleted file mode 100644 index 53c1ea77f..000000000 --- a/modules/cj-window-geometry.el +++ /dev/null @@ -1,81 +0,0 @@ -;;; cj-window-geometry.el --- Pure window-geometry helpers -*- lexical-binding: t; -*- - -;; Author: Craig Jennings - -;;; Commentary: - -;; Pure helpers for classifying a window's position in its frame and -;; computing body sizes. Shared between `ai-vterm.el' (F9 dispatch) -;; and `vterm-config.el' (F12 dispatch); the geometry- -;; preservation pattern in both modules captures direction + body -;; size at toggle-off and replays them on the next toggle-on. -;; -;; All functions are pure: they read window/frame edges and return -;; classifications. No side effects, no state. Consumers wrap them -;; with consumer-specific state vars and display logic. - -;;; Code: - -(defun cj/window-direction (window &optional default) - "Return the side WINDOW occupies in its frame. - -Returns one of right, below, left, above. Falls back to DEFAULT -(or right when DEFAULT is nil) when WINDOW fills its frame's -root area. Comparison uses `frame-root-window' edges so the -minibuffer doesn't make every full-area window look like it -fails to span the full height." - (let* ((root (frame-root-window (window-frame window))) - (edges (window-edges window)) - (root-edges (window-edges root)) - (left (nth 0 edges)) - (top (nth 1 edges)) - (right (nth 2 edges)) - (bottom (nth 3 edges)) - (root-left (nth 0 root-edges)) - (root-top (nth 1 root-edges)) - (root-right (nth 2 root-edges)) - (root-bottom (nth 3 root-edges)) - (spans-full-width (and (= left root-left) (= right root-right))) - (spans-full-height (and (= top root-top) (= bottom root-bottom)))) - (cond - ((not spans-full-width) (if (= left root-left) 'left 'right)) - ((not spans-full-height) (if (= top root-top) 'above 'below)) - (t (or default 'right))))) - -(defun cj/window-body-size (window direction) - "Return WINDOW's body size on the axis matching DIRECTION. - -Returns body-width (columns) when DIRECTION is right or left. -Returns body-height (lines) when DIRECTION is below or above. - -Body size, not total size, is the right thing to capture for -geometry replay: total-width includes the right-side divider when -the window has a right sibling but excludes it at the frame edge, -so a captured rightmost window replayed into a middle position -would leave the body 1 col short. Body size is divider- -independent and matches what the user actually sees." - (if (memq direction '(right left)) - (window-body-width window) - (window-body-height window))) - -(defun cj/cardinal-to-edge-direction (direction) - "Map cardinal DIRECTION to its `display-buffer-in-direction' edge variant. - -Returns rightmost/leftmost/bottom/top for right/left/below/above -respectively. Returns nil for any other input. - -The edge variants route splits relative to the frame's main -window rather than the selected window, so a toggle-on lands at -the same frame edge regardless of which window is selected. The -cardinal variants would split the selected window's tree branch -instead, putting the new window mid-frame in multi-window -layouts." - (pcase direction - ('right 'rightmost) - ('left 'leftmost) - ('below 'bottom) - ('above 'top) - (_ nil))) - -(provide 'cj-window-geometry) -;;; cj-window-geometry.el ends here diff --git a/modules/cj-window-toggle-lib.el b/modules/cj-window-toggle-lib.el index 868ee99ff..6021c2eb5 100644 --- a/modules/cj-window-toggle-lib.el +++ b/modules/cj-window-toggle-lib.el @@ -12,12 +12,12 @@ ;; helpers. Both helpers are pure with respect to their arguments; ;; the side effects are confined to the named state variables. ;; -;; Pulls the geometry primitives in from cj-window-geometry.el. +;; Pulls the geometry primitives in from cj-window-geometry-lib.el. ;;; Code: (require 'cl-lib) -(require 'cj-window-geometry) +(require 'cj-window-geometry-lib) (defun cj/window-toggle-capture-state (window default-direction direction-var size-var) diff --git a/modules/vterm-config.el b/modules/vterm-config.el index 9cf07abd4..e601ab403 100644 --- a/modules/vterm-config.el +++ b/modules/vterm-config.el @@ -24,7 +24,7 @@ (require 'keybindings) (require 'seq) (require 'subr-x) -(require 'cj-window-geometry) +(require 'cj-window-geometry-lib) (require 'cj-window-toggle-lib) (defvar-keymap cj/vterm-map diff --git a/tests/test-cj-window-geometry-lib.el b/tests/test-cj-window-geometry-lib.el new file mode 100644 index 000000000..b9410451d --- /dev/null +++ b/tests/test-cj-window-geometry-lib.el @@ -0,0 +1,103 @@ +;;; test-cj-window-geometry-lib.el --- Tests for the shared window-geometry helpers -*- lexical-binding: t; -*- + +;;; Commentary: +;; Tests the three pure helpers in `cj-window-geometry-lib.el': +;; `cj/window-direction', `cj/window-body-size', and +;; `cj/cardinal-to-edge-direction'. + +;;; Code: + +(require 'ert) + +(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory)) +(require 'cj-window-geometry-lib) + +(ert-deftest test-cj-window-geometry--direction-right-split () + "Normal: 2-window vertical split, right-side window -> right." + (save-window-excursion + (delete-other-windows) + (let ((right (split-window (selected-window) nil 'right))) + (should (eq (cj/window-direction right) 'right))))) + +(ert-deftest test-cj-window-geometry--direction-left-split () + "Normal: 2-window vertical split, left-side window -> left." + (save-window-excursion + (delete-other-windows) + (split-window (selected-window) nil 'right) + (should (eq (cj/window-direction (selected-window)) 'left)))) + +(ert-deftest test-cj-window-geometry--direction-below-split () + "Normal: 2-window horizontal split, bottom window -> below." + (save-window-excursion + (delete-other-windows) + (let ((below (split-window (selected-window) nil 'below))) + (should (eq (cj/window-direction below) 'below))))) + +(ert-deftest test-cj-window-geometry--direction-above-split () + "Normal: 2-window horizontal split, top window -> above." + (save-window-excursion + (delete-other-windows) + (split-window (selected-window) nil 'below) + (should (eq (cj/window-direction (selected-window)) 'above)))) + +(ert-deftest test-cj-window-geometry--direction-single-window-default-right () + "Boundary: single-window frame, no DEFAULT arg -> 'right." + (save-window-excursion + (delete-other-windows) + (should (eq (cj/window-direction (selected-window)) 'right)))) + +(ert-deftest test-cj-window-geometry--direction-single-window-with-default () + "Boundary: single-window frame with DEFAULT='below -> 'below." + (save-window-excursion + (delete-other-windows) + (should (eq (cj/window-direction (selected-window) 'below) 'below)))) + +(ert-deftest test-cj-window-geometry--body-size-right-returns-body-cols () + "Normal: right window with direction='right -> body-width in cols." + (save-window-excursion + (delete-other-windows) + (let ((right (split-window (selected-window) nil 'right))) + (should (= (cj/window-body-size right 'right) + (window-body-width right)))))) + +(ert-deftest test-cj-window-geometry--body-size-below-returns-body-lines () + "Normal: below window with direction='below -> body-height in lines." + (save-window-excursion + (delete-other-windows) + (let ((below (split-window (selected-window) nil 'below))) + (should (= (cj/window-body-size below 'below) + (window-body-height below)))))) + +(ert-deftest test-cj-window-geometry--body-size-narrow-window () + "Normal: deliberately narrow right window -> matching body cols." + (save-window-excursion + (delete-other-windows) + (let* ((frame-w (frame-width)) + (target-cols (/ frame-w 4)) + (right (split-window (selected-window) (- target-cols) 'right))) + (should (= (cj/window-body-size right 'right) + (window-body-width right)))))) + +(ert-deftest test-cj-window-geometry--cardinal-to-edge-right () + "Normal: 'right -> 'rightmost." + (should (eq (cj/cardinal-to-edge-direction 'right) 'rightmost))) + +(ert-deftest test-cj-window-geometry--cardinal-to-edge-left () + "Normal: 'left -> 'leftmost." + (should (eq (cj/cardinal-to-edge-direction 'left) 'leftmost))) + +(ert-deftest test-cj-window-geometry--cardinal-to-edge-below () + "Normal: 'below -> 'bottom." + (should (eq (cj/cardinal-to-edge-direction 'below) 'bottom))) + +(ert-deftest test-cj-window-geometry--cardinal-to-edge-above () + "Normal: 'above -> 'top." + (should (eq (cj/cardinal-to-edge-direction 'above) 'top))) + +(ert-deftest test-cj-window-geometry--cardinal-to-edge-unknown-returns-nil () + "Boundary: an unknown direction symbol -> nil." + (should (null (cj/cardinal-to-edge-direction 'sideways))) + (should (null (cj/cardinal-to-edge-direction nil)))) + +(provide 'test-cj-window-geometry-lib) +;;; test-cj-window-geometry-lib.el ends here diff --git a/tests/test-cj-window-geometry.el b/tests/test-cj-window-geometry.el deleted file mode 100644 index 8b0b97321..000000000 --- a/tests/test-cj-window-geometry.el +++ /dev/null @@ -1,103 +0,0 @@ -;;; test-cj-window-geometry.el --- Tests for the shared window-geometry helpers -*- lexical-binding: t; -*- - -;;; Commentary: -;; Tests the three pure helpers in `cj-window-geometry.el': -;; `cj/window-direction', `cj/window-body-size', and -;; `cj/cardinal-to-edge-direction'. - -;;; Code: - -(require 'ert) - -(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory)) -(require 'cj-window-geometry) - -(ert-deftest test-cj-window-geometry--direction-right-split () - "Normal: 2-window vertical split, right-side window -> right." - (save-window-excursion - (delete-other-windows) - (let ((right (split-window (selected-window) nil 'right))) - (should (eq (cj/window-direction right) 'right))))) - -(ert-deftest test-cj-window-geometry--direction-left-split () - "Normal: 2-window vertical split, left-side window -> left." - (save-window-excursion - (delete-other-windows) - (split-window (selected-window) nil 'right) - (should (eq (cj/window-direction (selected-window)) 'left)))) - -(ert-deftest test-cj-window-geometry--direction-below-split () - "Normal: 2-window horizontal split, bottom window -> below." - (save-window-excursion - (delete-other-windows) - (let ((below (split-window (selected-window) nil 'below))) - (should (eq (cj/window-direction below) 'below))))) - -(ert-deftest test-cj-window-geometry--direction-above-split () - "Normal: 2-window horizontal split, top window -> above." - (save-window-excursion - (delete-other-windows) - (split-window (selected-window) nil 'below) - (should (eq (cj/window-direction (selected-window)) 'above)))) - -(ert-deftest test-cj-window-geometry--direction-single-window-default-right () - "Boundary: single-window frame, no DEFAULT arg -> 'right." - (save-window-excursion - (delete-other-windows) - (should (eq (cj/window-direction (selected-window)) 'right)))) - -(ert-deftest test-cj-window-geometry--direction-single-window-with-default () - "Boundary: single-window frame with DEFAULT='below -> 'below." - (save-window-excursion - (delete-other-windows) - (should (eq (cj/window-direction (selected-window) 'below) 'below)))) - -(ert-deftest test-cj-window-geometry--body-size-right-returns-body-cols () - "Normal: right window with direction='right -> body-width in cols." - (save-window-excursion - (delete-other-windows) - (let ((right (split-window (selected-window) nil 'right))) - (should (= (cj/window-body-size right 'right) - (window-body-width right)))))) - -(ert-deftest test-cj-window-geometry--body-size-below-returns-body-lines () - "Normal: below window with direction='below -> body-height in lines." - (save-window-excursion - (delete-other-windows) - (let ((below (split-window (selected-window) nil 'below))) - (should (= (cj/window-body-size below 'below) - (window-body-height below)))))) - -(ert-deftest test-cj-window-geometry--body-size-narrow-window () - "Normal: deliberately narrow right window -> matching body cols." - (save-window-excursion - (delete-other-windows) - (let* ((frame-w (frame-width)) - (target-cols (/ frame-w 4)) - (right (split-window (selected-window) (- target-cols) 'right))) - (should (= (cj/window-body-size right 'right) - (window-body-width right)))))) - -(ert-deftest test-cj-window-geometry--cardinal-to-edge-right () - "Normal: 'right -> 'rightmost." - (should (eq (cj/cardinal-to-edge-direction 'right) 'rightmost))) - -(ert-deftest test-cj-window-geometry--cardinal-to-edge-left () - "Normal: 'left -> 'leftmost." - (should (eq (cj/cardinal-to-edge-direction 'left) 'leftmost))) - -(ert-deftest test-cj-window-geometry--cardinal-to-edge-below () - "Normal: 'below -> 'bottom." - (should (eq (cj/cardinal-to-edge-direction 'below) 'bottom))) - -(ert-deftest test-cj-window-geometry--cardinal-to-edge-above () - "Normal: 'above -> 'top." - (should (eq (cj/cardinal-to-edge-direction 'above) 'top))) - -(ert-deftest test-cj-window-geometry--cardinal-to-edge-unknown-returns-nil () - "Boundary: an unknown direction symbol -> nil." - (should (null (cj/cardinal-to-edge-direction 'sideways))) - (should (null (cj/cardinal-to-edge-direction nil)))) - -(provide 'test-cj-window-geometry) -;;; test-cj-window-geometry.el ends here -- cgit v1.2.3