aboutsummaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-05-10 03:48:44 -0500
committerCraig Jennings <c@cjennings.net>2026-05-10 03:48:44 -0500
commitc7771a7447d56c931b7ccf2a1675d7fe8bd4c800 (patch)
tree7dec1d786aeccdf77f99fb5af9a602eba65cc96f /modules
parent38b4a9acd3980a5bc9dbd3e60cec9f1fe847929a (diff)
downloaddotemacs-c7771a7447d56c931b7ccf2a1675d7fe8bd4c800.tar.gz
dotemacs-c7771a7447d56c931b7ccf2a1675d7fe8bd4c800.zip
fix(vterm): force a visible cursor in vterm-copy-mode
vterm's C module sets `cursor-type' to nil whenever the underlying TUI sends DECTCEM (`\e[?25l') to hide the terminal cursor. Most full-screen TUIs do this on startup — Claude Code in an ai-vterm being a daily example. Once the cursor is hidden at the buffer level, vterm-copy-mode inherits that nil and the user can't see where point is when navigating to select text. Selection still works, but you're flying blind. Add a `vterm-copy-mode-hook' that forces `cursor-type' to a 3-pixel bar on entry and kills the buffer-local override on exit. The bar shape is drawn between characters rather than by inverting one, so heavy TUI face properties don't hide it either. On exit the live terminal goes back to whatever vterm's tracking says, so the TUI's chosen cursor state resumes. 4 ERT tests cover the hook's enter/exit behavior and confirm registration on `vterm-copy-mode-hook'.
Diffstat (limited to 'modules')
-rw-r--r--modules/vterm-config.el17
1 files changed, 17 insertions, 0 deletions
diff --git a/modules/vterm-config.el b/modules/vterm-config.el
index 8442c65f6..eb472c574 100644
--- a/modules/vterm-config.el
+++ b/modules/vterm-config.el
@@ -381,6 +381,23 @@ C-F9 / M-F9 dispatch via `cj/ai-vterm'."
(cj/vterm-install-prefix-key)
(cj/vterm-install-copy-mode-cancel-keys))
+(defun cj/--vterm-copy-mode-restore-cursor ()
+ "Force a visible cursor on entry to `vterm-copy-mode'.
+
+The vterm C module sets `cursor-type' to nil whenever the underlying
+TUI sends DECTCEM (`\\e[?25l') to hide the terminal cursor — typical
+for full-screen TUIs like Claude Code. In `vterm-copy-mode' the user
+is navigating the buffer, not watching the TUI, so the cursor must
+be visible. Switches to a 3-pixel bar (drawn between characters
+rather than inverting one) so face-heavy TUI output doesn't hide it
+either. On exit, kills the buffer-local override so vterm's normal
+cursor-visibility tracking resumes."
+ (if vterm-copy-mode
+ (setq-local cursor-type '(bar . 3))
+ (kill-local-variable 'cursor-type)))
+
+(add-hook 'vterm-copy-mode-hook #'cj/--vterm-copy-mode-restore-cursor)
+
(add-hook 'vterm-mode-hook #'goto-address-mode)
(with-eval-after-load 'which-key