aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--modules/eat-config.el19
-rw-r--r--tests/test-term-tmux-history.el15
2 files changed, 33 insertions, 1 deletions
diff --git a/modules/eat-config.el b/modules/eat-config.el
index d8319e649..de919a00a 100644
--- a/modules/eat-config.el
+++ b/modules/eat-config.el
@@ -245,6 +245,16 @@ terminal. ai-term's agent buffers are managed separately via M-SPC."
(when (process-live-p proc)
(process-send-string proc string))))
+(defun cj/term-send-escape ()
+ "Send ESC to the terminal.
+In tmux copy-mode this cancels it (tmux binds Escape to cancel); in a TUI like
+vim it forwards ESC normally. EAT's semi-char mode leaves the bare escape key
+unbound and treats `ESC' only as the Meta prefix, so without this the key never
+reaches the pty -- which is why C-<up>'s tmux copy-mode could not be exited with
+Escape."
+ (interactive)
+ (cj/--term-send-string "\e"))
+
(defun cj/term--tmux-output (&rest args)
"Run tmux with ARGS and return its stdout.
Signal `user-error' when tmux exits with a non-zero status."
@@ -419,8 +429,15 @@ pty; without tmux, moves point up in EAT's emacs-mode buffer."
(keymap-set cj/term-map "h" #'cj/term-tmux-history)
(keymap-set cj/term-map "t" #'cj/term-toggle)
+(defvar eat-mode-map)
+(declare-function eat-semi-char-mode "eat")
(with-eval-after-load 'eat
- (keymap-set eat-semi-char-mode-map "C-<up>" #'cj/term-copy-mode-up))
+ (keymap-set eat-semi-char-mode-map "C-<up>" #'cj/term-copy-mode-up)
+ ;; Escape forwards ESC to the pty, so it cancels tmux copy-mode (tmux binds
+ ;; Escape to cancel) and works in TUIs; in EAT's own emacs/char mode it returns
+ ;; to semi-char. One key gets out of either copy view.
+ (keymap-set eat-semi-char-mode-map "<escape>" #'cj/term-send-escape)
+ (keymap-set eat-mode-map "<escape>" #'eat-semi-char-mode))
(provide 'eat-config)
;;; eat-config.el ends here
diff --git a/tests/test-term-tmux-history.el b/tests/test-term-tmux-history.el
index 633d7a02c..c7154e5d2 100644
--- a/tests/test-term-tmux-history.el
+++ b/tests/test-term-tmux-history.el
@@ -273,5 +273,20 @@ up-arrow -- it does not re-enter and reset the cursor."
(should (eq (keymap-lookup eat-semi-char-mode-map "C-<up>")
#'cj/term-copy-mode-up)))
+(ert-deftest test-term-escape-bound-as-unified-exit ()
+ "Normal: Escape sends ESC in semi-char mode (cancels tmux copy-mode) and
+returns to semi-char from EAT's emacs/char mode -- one exit key for both."
+ (should (eq (keymap-lookup eat-semi-char-mode-map "<escape>")
+ #'cj/term-send-escape))
+ (should (eq (keymap-lookup eat-mode-map "<escape>") #'eat-semi-char-mode)))
+
+(ert-deftest test-term-send-escape-writes-esc-to-pty ()
+ "Normal: `cj/term-send-escape' sends a bare ESC to the terminal process."
+ (let ((sent nil))
+ (cl-letf (((symbol-function 'cj/--term-send-string)
+ (lambda (s) (push s sent))))
+ (cj/term-send-escape)
+ (should (equal sent '("\e"))))))
+
(provide 'test-term-tmux-history)
;;; test-term-tmux-history.el ends here