Suppress cursor when cell face background matches cursor color#307
Suppress cursor when cell face background matches cursor color#307devsunb wants to merge 1 commit into
Conversation
A terminal app that draws its input cursor with SGR reverse-video (e.g. Claude Code) leaves the Emacs cursor visually fused with the cell beneath it. Emacs's GUI ports swap the cursor's fg/bg with the cell's fg/bg when cursor-color matches the cell background — see `set_cursor_gc' in xterm.c:8017 and the mac-port/w32/pgtk equivalents — and on a reverse-video cell, that swap reproduces the colors of the surrounding non-inverse cells. Detect the collision and force `cursor-type' to nil so the cell's own inverse video face represents the cursor. The check runs from a buffer-local `pre-redisplay-functions' hook rather than from `ghostel--set-cursor-style': a one-time assignment there would not stick, because cursor-type is restored to its default between module render passes, so the hook reapplies the suppression just before each redisplay. Track the DECTCEM hide state (`\e[?25l') in `ghostel--cursor-visible' along the way so the hook also keeps the cursor off when a TUI menu hides it.
|
@devsunb Thanks. Can you open an issue with more info and exact steps how to reproduce it? Neither claude nor gemini have any problems here. I set my focused cursor color exactly the same as the default fg, but everything works as expected. Also I'm not sure if a pre-redisplay-function that always runs and hides the cursor is the best solution. |
|
I found the root cause. The cursor was being redrawn by evil-mode, not by anything in this package. Sorry for the noise. For future reference, I had been disabling evil in ghostel buffers like this: (with-eval-after-load 'evil
(evil-set-initial-state 'ghostel-mode 'emacs))But emacs state still keeps evil active, so the cursor was being redrawn. The fix was to exclude the buffer from evil entirely: (with-eval-after-load 'evil
(add-to-list 'evil-buffer-regexps '("\\`\\*ghostel" . nil)))Thanks for the patient review and for creating this package. |
Summary
Hide the Emacs cursor when its color collides with the cursor cell's face background, so terminal apps that draw their own reverse-video cursor (Claude Code, Gemini CLI, etc.) stay visible.
Why
Emacs's GUI ports (X11, mac-port, w32, pgtk) share a
set_cursor_gcdistinct-swap fallback that swaps the cursor's fg/bg with the cell's fg/bg whenever they match (xterm.c:8017and the mac-port/w32/pgtk equivalents). It's meant to keep the cursor visible against a matching cell, but it backfires for apps that draw their input cursor via SGR reverse-video: on a reverse-video cell the swap reproduces the colors of the surrounding non-inverse cells, so the Emacs box cursor becomes visually indistinguishable from normal text.Fix
Detect the collision and force
cursor-typeoff so the cell's own reverse-video face represents the cursor:Suppression runs from a buffer-local
pre-redisplay-functionshook rather than fromghostel--set-cursor-style. A one-time assignment there would not stick, sincecursor-typeis restored to its default between module render passes; the hook reapplies the suppression just before each redisplay. It also keeps the cursor off when the terminal sends DECTCEM hide (\e[?25l), tracked inghostel--cursor-visible.Screenshots
Before
After