diff options
| -rw-r--r-- | modules/vterm-config.el | 9 | ||||
| -rw-r--r-- | tests/test-vterm-tmux-history.el | 48 | ||||
| -rw-r--r-- | todo.org | 35 |
3 files changed, 71 insertions, 21 deletions
diff --git a/modules/vterm-config.el b/modules/vterm-config.el index 764c9dcd..954e096a 100644 --- a/modules/vterm-config.el +++ b/modules/vterm-config.el @@ -121,7 +121,12 @@ returns to the vterm without copying. RET is left unbound." The history buffer uses normal Emacs navigation and selection. `M-w' copies the active region and stays open, so several pieces can be copied in a row; `q', `<escape>', or `C-g' returns point to the vterm -buffer that launched it." +buffer that launched it. + +The history view replaces the origin vterm buffer in the same window +(via `switch-to-buffer'), not a split or a popped-up window -- reading +past output should keep the agent's frame slot intact, and quit puts +the live terminal back where it was." (interactive) (let* ((origin-buffer (current-buffer)) (origin-window (selected-window)) @@ -139,7 +144,7 @@ buffer that launched it." (setq-local cj/vterm-tmux-history--origin-window origin-window) (setq-local cj/vterm-tmux-history--origin-point origin-point) (goto-char (point-max))) - (pop-to-buffer buffer))) + (switch-to-buffer buffer))) (defun cj/vterm-copy-mode-cancel () "Exit `vterm-copy-mode' without copying." diff --git a/tests/test-vterm-tmux-history.el b/tests/test-vterm-tmux-history.el index eec6c622..c0a71421 100644 --- a/tests/test-vterm-tmux-history.el +++ b/tests/test-vterm-tmux-history.el @@ -63,15 +63,12 @@ RESPONSES is an alist of (ARGS EXIT-CODE OUTPUT)." "Normal: command renders tmux history in a normal Emacs buffer." (let ((origin (cj/test--make-fake-vterm-buffer "*test-vterm-history-origin*"))) (unwind-protect - (with-current-buffer origin + (save-window-excursion + (switch-to-buffer origin) (cl-letf (((symbol-function 'get-buffer-process) (lambda (_buffer) 'fake-process)) ((symbol-function 'process-tty-name) - (lambda (_process) "/dev/pts/8")) - ((symbol-function 'pop-to-buffer) - (lambda (buffer &rest _) - (set-buffer buffer) - buffer))) + (lambda (_process) "/dev/pts/8"))) (test-vterm-tmux-history--with-tmux-mock '((("list-clients" "-F" "#{client_tty}\t#{pane_id}") 0 "/dev/pts/8\t%8\n") @@ -81,10 +78,45 @@ RESPONSES is an alist of (ARGS EXIT-CODE OUTPUT)." (should (eq major-mode 'cj/vterm-tmux-history-mode)) (should buffer-read-only) (should (string-match-p "history http://example.com" - (buffer-string))))))) + (buffer-string)))))) + (cj/test--kill-buffers-matching-prefix "*vterm tmux history") + (when (buffer-live-p origin) + (kill-buffer origin))))) + +(ert-deftest test-vterm-tmux-history-replaces-origin-buffer-in-same-window () + "Normal: the history view replaces the origin in the selected window. + +Before the in-place change, `cj/vterm-tmux-history' used `pop-to-buffer' +which could split or hand the buffer to a different window. The fix +uses `switch-to-buffer' so reading scrollback keeps the agent's frame +slot." + (let ((origin (cj/test--make-fake-vterm-buffer "*test-vterm-history-inplace*"))) + (unwind-protect + (save-window-excursion + (delete-other-windows) + (switch-to-buffer origin) + (let ((win (selected-window))) + (should (eq (window-buffer win) origin)) + (should (one-window-p)) + (cl-letf (((symbol-function 'get-buffer-process) + (lambda (_buffer) 'fake-process)) + ((symbol-function 'process-tty-name) + (lambda (_process) "/dev/pts/8"))) + (test-vterm-tmux-history--with-tmux-mock + '((("list-clients" "-F" "#{client_tty}\t#{pane_id}") 0 + "/dev/pts/8\t%8\n") + (("capture-pane" "-p" "-J" "-S" "-" "-E" "-" "-t" "%8") 0 + "scrollback line\n")) + (cj/vterm-tmux-history))) + ;; Same window, no split, history buffer now in the slot. + (should (one-window-p)) + (should (eq (selected-window) win)) + (should (string-prefix-p + "*vterm tmux history:" + (buffer-name (window-buffer win)))))) (cj/test--kill-buffers-matching-prefix "*vterm tmux history") (when (buffer-live-p origin) - (kill-buffer origin)))) + (kill-buffer origin))))) (ert-deftest test-vterm-tmux-history-quit-returns-to-origin () "Normal: q / <escape> / C-g (cj/vterm-tmux-history-quit) kills the history @@ -142,23 +142,36 @@ flag set on bury, flag cleared on delete-window, flag respected only when still one-window, flag not set when bury didn't run, and the end-to-end roundtrip. Full =make test-unit= green. -** TODO [#B] AI-vterm scrollback history should replace agent buffer in place :feature: +** DONE [#B] AI-vterm scrollback history should replace agent buffer in place :feature: When viewing the scrollback history of an AI-vterm buffer, the history view should replace the live agent buffer in the same window rather than splitting or popping a separate window. Goal: read past output without losing the agent's frame slot, then snap back to the live buffer when done. -Open questions before implementation: -- Is the trigger an existing command (e.g. =vterm-copy-mode= toggle staying - in-place) or a new command that builds a read-only history buffer? -- Round-trip ergonomics: how does the user return to the live agent? Same key as - the entry, or a separate "resume" binding? -- Does this need to integrate with the F9 toggle state (so a toggle-off while in - history mode does the right thing)? - -Locations: =modules/ai-vterm.el= (no scrollback-history command exists yet) and -=modules/vterm-config.el= (vterm base bindings). +Decisions on the open questions: +- *Trigger*: reused the existing =cj/vterm-tmux-history= command (=C-; x h=). + No new command -- it already captures the tmux pane and runs from any + vterm buffer including agents. +- *Round-trip*: =q= / =<escape>= / =C-g= already restore the origin in + the same window via =cj/vterm-tmux-history-quit=. Same key as the + scrollback mode's other exits. +- *F9 integration*: deferred. Pressing F9 in history mode now treats the + history buffer as non-agent (its name is =*vterm tmux history: ...*=, + not =agent [...]=) so dispatch falls through to redisplay-recent + a + saved-direction split. A user who wants to toggle agent off should + press =q= first, then F9. Filed as a follow-up if it bites. + +Fix: =modules/vterm-config.el= -- one line. =pop-to-buffer buffer= +became =switch-to-buffer buffer= so the history view replaces the origin +in the selected window instead of going through display-buffer's split +logic. Quit was already in-place via =set-window-buffer=. + +New test in =tests/test-vterm-tmux-history.el= asserts the selected +window's buffer becomes the history buffer with no extra window +created (=one-window-p= still t). Existing tests dropped their +=pop-to-buffer= stub since =switch-to-buffer= works directly in batch. +Full =make test-unit= green. ** TODO [#B] Add ERT coverage for modules below 70% :tests: |
