aboutsummaryrefslogtreecommitdiff
path: root/tests/test-cj-window-geometry-lib.el
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-05-25 04:10:38 -0500
committerCraig Jennings <c@cjennings.net>2026-05-25 04:10:38 -0500
commit3f75b39bbbc4e1c136d3f786024c5c1ed19011ce (patch)
treec03cfe18f7a067cae026db400e757cbd5d053d35 /tests/test-cj-window-geometry-lib.el
parent08014b2f15e099a1c5e662a17a41290f37aeebf4 (diff)
downloaddotemacs-3f75b39bbbc4e1c136d3f786024c5c1ed19011ce.tar.gz
dotemacs-3f75b39bbbc4e1c136d3f786024c5c1ed19011ce.zip
fix(ai-vterm): reuse the frame's half instead of splitting a third
F9 split a third window into a frame that was already divided in two, wedging the agent into the middle or a skinny extra column instead of taking the half it should occupy. The display rule only knew how to reuse a window already showing an agent or to split a fresh one. With a plain two-pane layout it fell through to the split and added a window. I added a display action, cj/--ai-vterm-reuse-edge-window, that reuses the window already forming the target half (the right column on a desktop, the bottom row on a laptop), found by a new cj/window-at-edge helper. It records the displaced buffer with display-buffer-record-window, so toggling off restores that buffer through the native quit-restore-window. The slot's buffer swaps between the agent and whatever it displaced, and no window is created or deleted. The split path still handles a single-window frame or a layout split on the other axis, and the lone fullscreen agent keeps its bury-and-restore-in-place behavior.
Diffstat (limited to 'tests/test-cj-window-geometry-lib.el')
-rw-r--r--tests/test-cj-window-geometry-lib.el75
1 files changed, 72 insertions, 3 deletions
diff --git a/tests/test-cj-window-geometry-lib.el b/tests/test-cj-window-geometry-lib.el
index b9410451..2b417425 100644
--- a/tests/test-cj-window-geometry-lib.el
+++ b/tests/test-cj-window-geometry-lib.el
@@ -1,9 +1,9 @@
;;; 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'.
+;; Tests the pure helpers in `cj-window-geometry-lib.el':
+;; `cj/window-direction', `cj/window-body-size',
+;; `cj/cardinal-to-edge-direction', and `cj/window-at-edge'.
;;; Code:
@@ -99,5 +99,74 @@
(should (null (cj/cardinal-to-edge-direction 'sideways)))
(should (null (cj/cardinal-to-edge-direction nil))))
+;; ----------------------------- cj/window-at-edge -----------------------------
+
+(ert-deftest test-cj-window-geometry--at-edge-2col-right-returns-right-column ()
+ "Normal: 2-column split -> the right column is the right-edge half."
+ (save-window-excursion
+ (delete-other-windows)
+ (let ((right (split-window (selected-window) nil 'right)))
+ (should (eq (cj/window-at-edge 'right) right)))))
+
+(ert-deftest test-cj-window-geometry--at-edge-2col-left-returns-left-column ()
+ "Normal: 2-column split -> the left column is the left-edge half."
+ (save-window-excursion
+ (delete-other-windows)
+ (let ((left (selected-window)))
+ (split-window (selected-window) nil 'right)
+ (should (eq (cj/window-at-edge 'left) left)))))
+
+(ert-deftest test-cj-window-geometry--at-edge-2row-below-returns-bottom-row ()
+ "Normal: 2-row split -> the bottom row is the below-edge half."
+ (save-window-excursion
+ (delete-other-windows)
+ (let ((below (split-window (selected-window) nil 'below)))
+ (should (eq (cj/window-at-edge 'below) below)))))
+
+(ert-deftest test-cj-window-geometry--at-edge-2row-above-returns-top-row ()
+ "Normal: 2-row split -> the top row is the above-edge half."
+ (save-window-excursion
+ (delete-other-windows)
+ (let ((top (selected-window)))
+ (split-window (selected-window) nil 'below)
+ (should (eq (cj/window-at-edge 'above) top)))))
+
+(ert-deftest test-cj-window-geometry--at-edge-single-window-returns-nil ()
+ "Boundary: a single-window frame has no distinct half -> nil for all sides."
+ (save-window-excursion
+ (delete-other-windows)
+ (dolist (dir '(right left below above))
+ (should (null (cj/window-at-edge dir))))))
+
+(ert-deftest test-cj-window-geometry--at-edge-axis-mismatch-returns-nil ()
+ "Boundary: a 2-row split has no right/left column; a 2-col split has no row."
+ (save-window-excursion
+ (delete-other-windows)
+ (split-window (selected-window) nil 'below)
+ (should (null (cj/window-at-edge 'right)))
+ (should (null (cj/window-at-edge 'left))))
+ (save-window-excursion
+ (delete-other-windows)
+ (split-window (selected-window) nil 'right)
+ (should (null (cj/window-at-edge 'below)))
+ (should (null (cj/window-at-edge 'above)))))
+
+(ert-deftest test-cj-window-geometry--at-edge-nested-right-split-returns-nil ()
+ "Boundary: when the right side is itself split into rows, no single
+window forms the full-height right half -> nil."
+ (save-window-excursion
+ (delete-other-windows)
+ (let ((right (split-window (selected-window) nil 'right)))
+ (split-window right nil 'below)
+ (should (null (cj/window-at-edge 'right))))))
+
+(ert-deftest test-cj-window-geometry--at-edge-unknown-direction-returns-nil ()
+ "Error: an unknown direction symbol -> nil even in a split frame."
+ (save-window-excursion
+ (delete-other-windows)
+ (split-window (selected-window) nil 'right)
+ (should (null (cj/window-at-edge 'sideways)))
+ (should (null (cj/window-at-edge nil)))))
+
(provide 'test-cj-window-geometry-lib)
;;; test-cj-window-geometry-lib.el ends here