aboutsummaryrefslogtreecommitdiff
path: root/tests/test-ai-term--display-rule.el
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-06-05 05:28:58 -0500
committerCraig Jennings <c@cjennings.net>2026-06-05 05:28:58 -0500
commitebdf9e466b0e1f86e9b7d76650ac32408273e7a7 (patch)
treedab9b453f3a93c324b5388b3843502a088c7ed46 /tests/test-ai-term--display-rule.el
parentc094b2e4e64530379a9cb273303308a9affcabf6 (diff)
downloaddotemacs-ebdf9e466b0e1f86e9b7d76650ac32408273e7a7.tar.gz
dotemacs-ebdf9e466b0e1f86e9b7d76650ac32408273e7a7.zip
feat(term): replace vterm with ghostel as the terminal engine
I swapped the terminal engine from vterm to ghostel (libghostty-vt) everywhere. term-config replaces vterm-config (the F12 terminal, the C-; x menu, tmux history capture), and ai-term replaces ai-vterm (the F9 Claude-agent launcher). ghostel renders the agent TUI without vterm's flicker under heavy streaming, and one engine now covers every terminal workflow. Two behavior changes fall out of the swap. F9 launches in a terminal frame now: ghostel renders in TTY frames, so the old GUI-only guard is gone. Terminal windows no longer dim when unfocused: ghostel resolves its palette into the native module per-terminal, so there's no per-window color hook to dim through the way vterm had. auto-dim drops its vterm color-advice path, the dashboard Terminal button launches ghostel, and the vterm and vterm-toggle packages are removed. The tmux pane-history and copy-mode machinery carried over unchanged. It keys on the pty tty, which ghostel exposes.
Diffstat (limited to 'tests/test-ai-term--display-rule.el')
-rw-r--r--tests/test-ai-term--display-rule.el78
1 files changed, 78 insertions, 0 deletions
diff --git a/tests/test-ai-term--display-rule.el b/tests/test-ai-term--display-rule.el
new file mode 100644
index 00000000..906a4768
--- /dev/null
+++ b/tests/test-ai-term--display-rule.el
@@ -0,0 +1,78 @@
+;;; test-ai-term--display-rule.el --- Tests for the AI-term display-buffer rule -*- lexical-binding: t; -*-
+
+;;; Commentary:
+;; The module installs a `display-buffer-alist' entry routing buffers
+;; whose names match "\\`agent \\[" to a right-side window. These
+;; tests verify the rule reaches the right side and ignores buffers
+;; that don't match the prefix.
+
+;;; Code:
+
+(require 'ert)
+(require 'cl-lib)
+
+(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory))
+(require 'ai-term)
+
+(defun test-ai-term--cleanup (name)
+ "Kill buffer NAME if it exists."
+ (when (get-buffer name)
+ (kill-buffer name)))
+
+(defmacro test-ai-term--with-clean-frame (&rest body)
+ "Run BODY in a context with one window and the AI-term rule loaded."
+ (declare (indent 0) (debug t))
+ `(save-window-excursion
+ (delete-other-windows)
+ (let ((display-buffer-alist (cj/--ai-term-display-rule-list)))
+ ,@body)))
+
+(ert-deftest test-ai-term--display-rule-routes-agent-buffer-to-right ()
+ "Normal: on a desktop, \"agent [foo]\" lands in a window to the right.
+
+The desktop default direction is `right' (see
+`cj/--ai-term-default-direction'), so the rule splits the current
+window with `(direction . right)' and the new window's left edge
+sits at a positive column. `env-laptop-p' is stubbed nil to pin the
+desktop branch; on a laptop the agent would land below instead."
+ (let ((name "agent [display-rule-test]"))
+ (test-ai-term--cleanup name)
+ (unwind-protect
+ (cl-letf (((symbol-function 'env-laptop-p) (lambda () nil)))
+ (test-ai-term--with-clean-frame
+ (let* ((buf (get-buffer-create name))
+ (win (display-buffer buf)))
+ (should (windowp win))
+ (should (> (window-left-column win) 0)))))
+ (test-ai-term--cleanup name))))
+
+(ert-deftest test-ai-term--display-rule-skips-non-matching-buffer ()
+ "Boundary: a buffer not named \"agent [...]\" does not match the rule.
+
+The rule's regex doesn't fire, so `display-buffer' falls back to the
+default action -- reuse the current window -- and no rightward split
+occurs."
+ (let ((name "scratch-buffer-no-match"))
+ (test-ai-term--cleanup name)
+ (unwind-protect
+ (test-ai-term--with-clean-frame
+ (let* ((buf (get-buffer-create name))
+ (win (display-buffer buf)))
+ (should (windowp win))
+ (should (= (window-left-column win) 0))))
+ (test-ai-term--cleanup name))))
+
+(ert-deftest test-ai-term--display-rule-prefix-not-substring ()
+ "Boundary: \"foo agent [bar]\" does not match -- the rule anchors at start."
+ (let ((name "foo agent [substring-test]"))
+ (test-ai-term--cleanup name)
+ (unwind-protect
+ (test-ai-term--with-clean-frame
+ (let* ((buf (get-buffer-create name))
+ (win (display-buffer buf)))
+ (should (windowp win))
+ (should (= (window-left-column win) 0))))
+ (test-ai-term--cleanup name))))
+
+(provide 'test-ai-term--display-rule)
+;;; test-ai-term--display-rule.el ends here