summaryrefslogtreecommitdiff
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
commit3003683a24cf38dbd2eeeaee6244ad0c1bbe72ee (patch)
tree7dec1d786aeccdf77f99fb5af9a602eba65cc96f /modules
parentb099c779343119ce40f2636469e118ec104002e0 (diff)
downloaddotemacs-3003683a24cf38dbd2eeeaee6244ad0c1bbe72ee.tar.gz
dotemacs-3003683a24cf38dbd2eeeaee6244ad0c1bbe72ee.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 8442c65f..eb472c57 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