summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--modules/ai-vterm.el74
-rw-r--r--tests/test-ai-vterm--f9-in-vterm.el13
-rw-r--r--tests/test-ai-vterm--pick-buffer-candidates.el80
3 files changed, 18 insertions, 149 deletions
diff --git a/modules/ai-vterm.el b/modules/ai-vterm.el
index 975374f6..108a73ca 100644
--- a/modules/ai-vterm.el
+++ b/modules/ai-vterm.el
@@ -32,10 +32,10 @@
;; picker, even when an agent buffer is currently displayed.
;; Used when the user wants to start a new project session
;; instead of toggling the current one.
-;; - M-F9 `cj/ai-vterm-pick-buffer' -- pick from the alive agent
-;; buffers (no project candidates, no creation). When an agent
-;; buffer is currently displayed, the picked buffer replaces it
-;; in that window so orientation and size are preserved.
+;; - M-F9 `cj/toggle-gptel' -- toggle gptel's *AI-Assistant* window.
+;; Lives outside this module (defined in `modules/ai-config.el')
+;; but the binding is grouped with the other F9-family launchers
+;; here so the dispatch shape is visible in one place.
;;
;; Existing windmove (Shift-arrows) handles code <-> agent focus
;; toggling. Buffer-move (C-M-arrows) handles side-swap. Neither
@@ -595,27 +595,6 @@ without firing real `display-buffer' or `quit-window' calls."
(buffers (cons 'redisplay-recent (car buffers)))
(t '(pick-project))))))))
-(defun cj/--ai-vterm-pick-buffer-candidates (buffers shown-buffer)
- "Build the M-F9 picker alist.
-
-BUFFERS is an MRU-ordered list of alive AI-vterm buffers.
-SHOWN-BUFFER is the AI-vterm buffer currently displayed in this frame,
-or nil.
-
-When SHOWN-BUFFER is one of BUFFERS, it sorts last with a
-\" [shown]\" suffix so the default `completing-read' selection lands
-on a non-shown candidate (i.e. RET picks \"the other one\"). When
-SHOWN-BUFFER is not in BUFFERS (a stale window state), every entry is
-treated as non-shown.
-
-Each cell is (DISPLAY-NAME . BUFFER)."
- (let ((non-shown (seq-remove (lambda (b) (eq b shown-buffer)) buffers))
- (shown (when (memq shown-buffer buffers) shown-buffer)))
- (append
- (mapcar (lambda (b) (cons (buffer-name b) b)) non-shown)
- (when shown
- (list (cons (format "%s [shown]" (buffer-name shown)) shown))))))
-
(defun cj/ai-vterm-pick-project (&optional arg)
"Pick an AI-agent project and open or reuse its vterm.
@@ -638,41 +617,6 @@ buffer is currently displayed."
(when win (select-window win))))
buf))
-(defun cj/ai-vterm-pick-buffer ()
- "Pick from the alive AI-vterm buffers; switch to the chosen one.
-
-When an AI-vterm buffer is currently displayed in this frame, the
-picked buffer replaces it in the same window via `set-window-buffer'.
-Orientation and size are preserved so the user's split layout doesn't
-change. When no AI-vterm buffer is displayed, default placement
-applies via `display-buffer'.
-
-The currently-displayed buffer (if any) is sorted last in the picker
-with a \" [shown]\" suffix; the default selection lands on a
-non-shown candidate so RET means \"give me the other one\".
-
-Signals `user-error' when no AI-vterm buffers exist.
-
-Bound to M-F9."
- (interactive)
- (let ((buffers (cj/--ai-vterm-agent-buffers)))
- (unless buffers
- (user-error "No agent buffers"))
- (let* ((shown-win (cj/--ai-vterm-displayed-agent-window))
- (shown-buf (and shown-win (window-buffer shown-win)))
- (alist (cj/--ai-vterm-pick-buffer-candidates buffers shown-buf))
- (chosen (completing-read "AI vterm buffer: " alist nil t))
- (buf (cdr (assoc chosen alist))))
- (cond
- ((and shown-win (window-live-p shown-win))
- (set-window-buffer shown-win buf)
- (select-window shown-win))
- (t
- (display-buffer buf)
- (let ((w (get-buffer-window buf)))
- (when w (select-window w)))))
- buf)))
-
(defun cj/ai-vterm (&optional arg)
"Smart F9 dispatch for the AI-vterm launcher.
@@ -687,9 +631,9 @@ Behavior depends on the current state:
With prefix ARG, display the buffer without selecting its window
when a buffer is being shown (no effect on the toggle-off branch).
-See `cj/ai-vterm-pick-project' (C-F9) to force the project picker
-and `cj/ai-vterm-pick-buffer' (M-F9) to switch among existing
-AI-vterm buffers without touching the project list."
+See `cj/ai-vterm-pick-project' (C-F9) to force the project picker.
+M-F9 toggles gptel's *AI-Assistant* window (`cj/toggle-gptel',
+defined in `modules/ai-config.el')."
(interactive "P")
(pcase (cj/--ai-vterm-dispatch)
(`(toggle-off . ,win)
@@ -738,7 +682,7 @@ AI-vterm buffers without touching the project list."
(keymap-global-set "<f9>" #'cj/ai-vterm)
(keymap-global-set "C-<f9>" #'cj/ai-vterm-pick-project)
-(keymap-global-set "M-<f9>" #'cj/ai-vterm-pick-buffer)
+(keymap-global-set "M-<f9>" #'cj/toggle-gptel)
;; vterm binds <f1>..<f12> to `vterm--self-insert', so a plain <f9> typed
;; while point is inside an agent buffer gets sent to the terminal program
@@ -749,7 +693,7 @@ AI-vterm buffers without touching the project list."
(with-eval-after-load 'vterm
(keymap-set vterm-mode-map "<f9>" #'cj/ai-vterm)
(keymap-set vterm-mode-map "C-<f9>" #'cj/ai-vterm-pick-project)
- (keymap-set vterm-mode-map "M-<f9>" #'cj/ai-vterm-pick-buffer))
+ (keymap-set vterm-mode-map "M-<f9>" #'cj/toggle-gptel))
;; ---------- emacsclient: keep opened files off the agent vterm ----------
;;
diff --git a/tests/test-ai-vterm--f9-in-vterm.el b/tests/test-ai-vterm--f9-in-vterm.el
index 1355bd6a..ff8939c8 100644
--- a/tests/test-ai-vterm--f9-in-vterm.el
+++ b/tests/test-ai-vterm--f9-in-vterm.el
@@ -24,19 +24,24 @@
(should (eq (keymap-lookup vterm-mode-map "<f9>") #'cj/ai-vterm)))
(ert-deftest test-ai-vterm-f9-family-bound-in-vterm-mode-map ()
- "Normal: the C-/M- F9 variants are bound in `vterm-mode-map' too."
+ "Normal: the C-/M- F9 variants are bound in `vterm-mode-map' too.
+`M-<f9>' toggles gptel's *AI-Assistant* window (rebound here from
+the old `cj/ai-vterm-pick-buffer' command, which was removed)."
(should (eq (keymap-lookup vterm-mode-map "C-<f9>") #'cj/ai-vterm-pick-project))
- (should (eq (keymap-lookup vterm-mode-map "M-<f9>") #'cj/ai-vterm-pick-buffer)))
+ (should (eq (keymap-lookup vterm-mode-map "M-<f9>") #'cj/toggle-gptel)))
(ert-deftest test-ai-vterm-f9-not-self-insert-in-vterm ()
"Boundary: vterm's default <f9> -> `vterm--self-insert' was overridden."
(should-not (eq (keymap-lookup vterm-mode-map "<f9>") 'vterm--self-insert)))
(ert-deftest test-ai-vterm-f9-still-bound-globally ()
- "Normal: the global F9 family bindings are intact."
+ "Normal: the global F9 family bindings are intact.
+`<f9>' toggles the ai-vterm agent window; `C-<f9>' picks a project
+agent; `M-<f9>' toggles gptel's *AI-Assistant* window (rebound from
+the retired `cj/ai-vterm-pick-buffer')."
(should (eq (lookup-key (current-global-map) (kbd "<f9>")) #'cj/ai-vterm))
(should (eq (lookup-key (current-global-map) (kbd "C-<f9>")) #'cj/ai-vterm-pick-project))
- (should (eq (lookup-key (current-global-map) (kbd "M-<f9>")) #'cj/ai-vterm-pick-buffer)))
+ (should (eq (lookup-key (current-global-map) (kbd "M-<f9>")) #'cj/toggle-gptel)))
(provide 'test-ai-vterm--f9-in-vterm)
;;; test-ai-vterm--f9-in-vterm.el ends here
diff --git a/tests/test-ai-vterm--pick-buffer-candidates.el b/tests/test-ai-vterm--pick-buffer-candidates.el
deleted file mode 100644
index c32039de..00000000
--- a/tests/test-ai-vterm--pick-buffer-candidates.el
+++ /dev/null
@@ -1,80 +0,0 @@
-;;; test-ai-vterm--pick-buffer-candidates.el --- Tests for the M-F9 candidate builder -*- lexical-binding: t; -*-
-
-;;; Commentary:
-;; The candidate builder is a pure function: given an MRU list of
-;; alive AI-vterm buffers and the currently-displayed buffer (or
-;; nil), it returns an alist of (DISPLAY-NAME . BUFFER) cells.
-;;
-;; Sort rule: non-shown buffers come first in their input order,
-;; then the shown buffer (if it's in the list) appears last with a
-;; \" [shown]\" suffix. The intent is that the default `completing-
-;; read' selection lands on a non-shown candidate so RET means
-;; \"give me the other one\".
-
-;;; Code:
-
-(require 'ert)
-
-(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory))
-(add-to-list 'load-path (expand-file-name "tests" user-emacs-directory))
-(require 'ai-vterm)
-(require 'testutil-vterm-buffers)
-
-(ert-deftest test-ai-vterm--pick-buffer-candidates-empty-buffers ()
- "Boundary: empty buffer list -> empty alist regardless of shown."
- (cj/test--kill-agent-buffers)
- (should (null (cj/--ai-vterm-pick-buffer-candidates nil nil)))
- (should (null (cj/--ai-vterm-pick-buffer-candidates nil 'sentinel))))
-
-(ert-deftest test-ai-vterm--pick-buffer-candidates-shown-nil ()
- "Normal: shown is nil -> straight alist in input order, no marker."
- (cj/test--kill-agent-buffers)
- (let ((b1 (get-buffer-create "agent [a]"))
- (b2 (get-buffer-create "agent [b]")))
- (unwind-protect
- (let ((result (cj/--ai-vterm-pick-buffer-candidates (list b1 b2) nil)))
- (should (equal result `(("agent [a]" . ,b1)
- ("agent [b]" . ,b2)))))
- (kill-buffer b1)
- (kill-buffer b2))))
-
-(ert-deftest test-ai-vterm--pick-buffer-candidates-shown-promotes-non-shown ()
- "Normal: shown buffer sorts last with [shown] suffix; others first."
- (cj/test--kill-agent-buffers)
- (let ((b1 (get-buffer-create "agent [a]"))
- (b2 (get-buffer-create "agent [b]"))
- (b3 (get-buffer-create "agent [c]")))
- (unwind-protect
- (let ((result (cj/--ai-vterm-pick-buffer-candidates
- (list b1 b2 b3) b1)))
- (should (equal result
- `(("agent [b]" . ,b2)
- ("agent [c]" . ,b3)
- ("agent [a] [shown]" . ,b1)))))
- (kill-buffer b1)
- (kill-buffer b2)
- (kill-buffer b3))))
-
-(ert-deftest test-ai-vterm--pick-buffer-candidates-shown-only-buffer ()
- "Boundary: shown is the only entry -> single cell with [shown] marker."
- (cj/test--kill-agent-buffers)
- (let ((b1 (get-buffer-create "agent [a]")))
- (unwind-protect
- (let ((result (cj/--ai-vterm-pick-buffer-candidates (list b1) b1)))
- (should (equal result `(("agent [a] [shown]" . ,b1)))))
- (kill-buffer b1))))
-
-(ert-deftest test-ai-vterm--pick-buffer-candidates-shown-not-in-buffers ()
- "Boundary: stale shown buffer not in list -> all cells are non-shown."
- (cj/test--kill-agent-buffers)
- (let ((b1 (get-buffer-create "agent [a]"))
- (b-stale (get-buffer-create "agent [stale]")))
- (unwind-protect
- (let ((result (cj/--ai-vterm-pick-buffer-candidates
- (list b1) b-stale)))
- (should (equal result `(("agent [a]" . ,b1)))))
- (kill-buffer b1)
- (kill-buffer b-stale))))
-
-(provide 'test-ai-vterm--pick-buffer-candidates)
-;;; test-ai-vterm--pick-buffer-candidates.el ends here