diff options
Diffstat (limited to 'modules')
| -rw-r--r-- | modules/ai-vterm.el | 72 | ||||
| -rw-r--r-- | modules/cj-window-toggle.el | 85 | ||||
| -rw-r--r-- | modules/eshell-vterm-config.el | 48 |
3 files changed, 109 insertions, 96 deletions
diff --git a/modules/ai-vterm.el b/modules/ai-vterm.el index e817f441..482f6522 100644 --- a/modules/ai-vterm.el +++ b/modules/ai-vterm.el @@ -37,6 +37,7 @@ (require 'cl-lib) (require 'seq) (require 'cj-window-geometry) +(require 'cj-window-toggle) (declare-function vterm "vterm" (&optional buffer-name)) (declare-function vterm-send-string "vterm" (string &optional paste-p)) @@ -235,15 +236,12 @@ cost of not auto-scaling if the frame itself resizes.") Sets `cj/--ai-vterm-last-direction' and `cj/--ai-vterm-last-size' so a subsequent F9 display can restore the user's chosen orientation and size. Called at toggle-off (just before the window is torn -down). The default direction is 'right -- the module's side-panel -default. - -Does nothing when WINDOW is not live." - (when (window-live-p window) - (let* ((dir (cj/window-direction window 'right)) - (size (cj/window-body-size window dir))) - (setq cj/--ai-vterm-last-direction dir - cj/--ai-vterm-last-size size)))) +down). The default direction is `right' -- the module's side-panel +default. Does nothing when WINDOW is not live." + (cj/window-toggle-capture-state + window 'right + 'cj/--ai-vterm-last-direction + 'cj/--ai-vterm-last-size)) (defun cj/--ai-vterm-reuse-existing-claude (buffer _alist) "Display-buffer action: reuse any window in this frame already showing @@ -268,56 +266,12 @@ project changes." (defun cj/--ai-vterm-display-saved (buffer alist) "Display-buffer action: split per saved direction and size. -Reads `cj/--ai-vterm-last-direction' and `cj/--ai-vterm-last-size' -(falling back to right and `cj/ai-vterm-window-width' when nil) and -delegates to `display-buffer-in-direction' with an alist that carries -the saved values. - -The captured cardinal direction (right/left/below/above) is mapped -to its frame-edge variant (rightmost/leftmost/bottom/top) so the new -claude always lands at the same frame edge it came from. This -means: the new window splits the frame's main window at the -matching edge, not whatever window happens to be selected when F9 -fires. Without this mapping, a toggle-off-on cycle in a 3+ window -layout would put claude into a middle position (right of the -selected window) rather than the edge it lived on before. As a -side benefit, claude always lands without a sibling on its -captured-edge side, so its body-width and total-width match -- no -divider chrome eating 1 col per toggle. - -An integer size (the captured absolute body-cols or body-lines) is -wrapped in a `(body-columns . N)' / `(body-lines . N)' cons so -`display-buffer-in-direction' sets the body width or body height -exactly. A float size (the customizable default fallback) passes -through as a fraction of the new window's parent. - -Any direction/window-width/window-height entries in ALIST are -stripped so the saved-state values control placement -- callers -shouldn't specify direction or size in the rule when this action is -used." - (let* ((direction (or cj/--ai-vterm-last-direction 'right)) - (edge-direction (or (cj/cardinal-to-edge-direction direction) - 'rightmost)) - (size (or cj/--ai-vterm-last-size cj/ai-vterm-window-width)) - (size-key (if (memq direction '(right left)) - 'window-width - 'window-height)) - (body-tag (if (memq direction '(right left)) - 'body-columns - 'body-lines)) - (size-value (if (integerp size) - (cons body-tag size) - size)) - (filtered (cl-remove-if - (lambda (cell) - (memq (car-safe cell) - '(direction window-width window-height))) - alist)) - (effective (append - (list (cons 'direction edge-direction) - (cons size-key size-value)) - filtered))) - (display-buffer-in-direction buffer effective))) +Delegates to `cj/window-toggle-display-saved' against the F9 state +vars, falling back to `right' and `cj/ai-vterm-window-width'." + (cj/window-toggle-display-saved + buffer alist + 'cj/--ai-vterm-last-direction 'right + 'cj/--ai-vterm-last-size cj/ai-vterm-window-width)) (defun cj/--ai-vterm-display-rule-list () "Return the `display-buffer-alist' entry list installed by this module. diff --git a/modules/cj-window-toggle.el b/modules/cj-window-toggle.el new file mode 100644 index 00000000..016b1967 --- /dev/null +++ b/modules/cj-window-toggle.el @@ -0,0 +1,85 @@ +;;; cj-window-toggle.el --- Shared toggle-state helpers for display-buffer dispatchers -*- lexical-binding: t; -*- + +;; Author: Craig Jennings <c@cjennings.net> + +;;; Commentary: + +;; Parameterized helpers used by ai-vterm.el (F9) and +;; eshell-vterm-config.el (F12) to capture a window's geometry at +;; toggle-off and replay it on the next toggle-on. Each consumer +;; holds its own pair of state variables (last-direction symbol + +;; last-size integer/float) and passes the variable symbols to the +;; 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. + +;;; Code: + +(require 'cl-lib) +(require 'cj-window-geometry) + +(defun cj/window-toggle-capture-state (window default-direction + direction-var size-var) + "Write WINDOW's direction and body size into DIRECTION-VAR and SIZE-VAR. + +DEFAULT-DIRECTION is the symbol used by `cj/window-direction' when +WINDOW fills its frame's root area. DIRECTION-VAR and SIZE-VAR are +the symbols of the consumer's state variables; they receive the +captured values via `set'. + +No-op when WINDOW is nil or not live." + (when (window-live-p window) + (let* ((dir (cj/window-direction window default-direction)) + (size (cj/window-body-size window dir))) + (set direction-var dir) + (set size-var size)))) + +(defun cj/window-toggle-display-saved (buffer alist + direction-var default-direction + size-var default-size) + "Display-buffer action: split per saved DIRECTION-VAR and SIZE-VAR. + +Reads the consumer's stored direction and size through DIRECTION-VAR +and SIZE-VAR (symbols); falls back to DEFAULT-DIRECTION and +DEFAULT-SIZE when the stored values are nil. The cardinal direction +is mapped to its frame-edge variant via +`cj/cardinal-to-edge-direction' so the new buffer always lands at +the same frame edge regardless of the selected window. An integer +size is wrapped in a `(body-columns . N)' / `(body-lines . N)' cons +so `display-buffer-in-direction' sets the body explicitly, +divider-independent. A float size passes through as a fraction of +the new window's parent. + +Caller-supplied ALIST entries for direction, window-width, or +window-height are stripped before delegating to +`display-buffer-in-direction' so the saved-state values control +placement; the remaining alist entries are passed through." + (let* ((stored-dir (and (boundp direction-var) (symbol-value direction-var))) + (stored-size (and (boundp size-var) (symbol-value size-var))) + (direction (or stored-dir default-direction)) + (edge-direction (or (cj/cardinal-to-edge-direction direction) + (cj/cardinal-to-edge-direction default-direction))) + (size (or stored-size default-size)) + (size-key (if (memq direction '(right left)) + 'window-width + 'window-height)) + (body-tag (if (memq direction '(right left)) + 'body-columns + 'body-lines)) + (size-value (if (integerp size) + (cons body-tag size) + size)) + (filtered (cl-remove-if + (lambda (cell) + (memq (car-safe cell) + '(direction window-width window-height))) + alist)) + (effective (append + (list (cons 'direction edge-direction) + (cons size-key size-value)) + filtered))) + (display-buffer-in-direction buffer effective))) + +(provide 'cj-window-toggle) +;;; cj-window-toggle.el ends here diff --git a/modules/eshell-vterm-config.el b/modules/eshell-vterm-config.el index dff31e4d..165e0437 100644 --- a/modules/eshell-vterm-config.el +++ b/modules/eshell-vterm-config.el @@ -396,6 +396,7 @@ ai-vterm.el is loaded." (require 'cl-lib) (require 'seq) (require 'cj-window-geometry) +(require 'cj-window-toggle) (defcustom cj/vterm-toggle-window-height 0.7 "Default fraction of frame height for the F12 vterm window. @@ -446,47 +447,20 @@ FRAME defaults to the selected frame. Minibuffer is excluded." Default direction is `below' to match F12's traditional bottom split when WINDOW fills the frame's root area." - (when (window-live-p window) - (let* ((dir (cj/window-direction window 'below)) - (size (cj/window-body-size window dir))) - (setq cj/--vterm-toggle-last-direction dir - cj/--vterm-toggle-last-size size)))) + (cj/window-toggle-capture-state + window 'below + 'cj/--vterm-toggle-last-direction + 'cj/--vterm-toggle-last-size)) (defun cj/--vterm-toggle-display-saved (buffer alist) "Display-buffer action: split per saved direction and body size. -Reads `cj/--vterm-toggle-last-direction' and -`cj/--vterm-toggle-last-size', falling back to `below' and -`cj/vterm-toggle-window-height' when nil. The cardinal direction -is mapped to its frame-edge variant (`right' -> `rightmost', etc.) -so the new vterm always lands at the same frame edge it came from -regardless of which window is selected. An integer size is wrapped -in a `(body-columns . N)' / `(body-lines . N)' cons so the body -width or height is set explicitly, divider-independent. A float -size passes through as a fraction of the new window's parent." - (let* ((direction (or cj/--vterm-toggle-last-direction 'below)) - (edge-direction (or (cj/cardinal-to-edge-direction direction) - 'bottom)) - (size (or cj/--vterm-toggle-last-size cj/vterm-toggle-window-height)) - (size-key (if (memq direction '(right left)) - 'window-width - 'window-height)) - (body-tag (if (memq direction '(right left)) - 'body-columns - 'body-lines)) - (size-value (if (integerp size) - (cons body-tag size) - size)) - (filtered (cl-remove-if - (lambda (cell) - (memq (car-safe cell) - '(direction window-width window-height))) - alist)) - (effective (append - (list (cons 'direction edge-direction) - (cons size-key size-value)) - filtered))) - (display-buffer-in-direction buffer effective))) +Delegates to `cj/window-toggle-display-saved' against the F12 state +vars, falling back to `below' and `cj/vterm-toggle-window-height'." + (cj/window-toggle-display-saved + buffer alist + 'cj/--vterm-toggle-last-direction 'below + 'cj/--vterm-toggle-last-size cj/vterm-toggle-window-height)) (defun cj/--vterm-toggle-display-rule-list () "Return the `display-buffer-alist' entry list installed by F12. |
