evil-ghostel: anchor-inhibit hook so point can roam over an animated terminal (#454)#484
Merged
Conversation
dakra
force-pushed
the
evil-anchor-inhibit-hook
branch
from
June 29, 2026 21:00
35b6480 to
339e47e
Compare
dakra
force-pushed
the
evil-anchor-inhibit-hook
branch
3 times, most recently
from
June 30, 2026 07:43
ad4079b to
5bf2290
Compare
Per-redraw anchoring snapped point to the live terminal cursor in every follow-capable input mode, so evil normal-state motion (hjkl) over an animated terminal was yanked back to the cursor ~30 times a second (issue #454). Add a `ghostel-inhibit-anchor-functions' abnormal hook: a non-nil return from any function skips anchoring that window (neither viewport nor point moves) for the redraw. FORCE anchors (paste/yank, mode switches) still win. evil-ghostel registers a buffer-local predicate that vetoes while point roams off the cursor in a motion-capable evil state, replacing the brittle define-advice workaround from the issue. The predicate is scoped to where evil-ghostel drives PTY input (`evil-ghostel--active-p': semi-char, outside alt-screen), so the other input modes keep ghostel's own anchor handling. The deliberate mode-switch anchors in `ghostel-semi-char-mode'/`ghostel-char-mode' now pass FORCE so an explicit switch always snaps back to the prompt.
In insert/emacs state `evil-ghostel--around-redraw' re-synced point to the live terminal cursor on every redraw, so a wheel-scroll into scrollback was yanked back to the bottom ~30 times a second under an animated terminal (issue #454, seam 2) — redisplay re-scrolls to keep the dragged point visible. Gate that re-sync on `evil-ghostel--window-following-p': follow the cursor only while the window still tracks the live output (or no window shows the buffer). Once the user scrolls into scrollback the window stops following, so point is left put and the viewport holds its position.
…ostel `(interactive "*P")' ran barf-if-buffer-read-only before the body, so p/P errored "Buffer is read-only" in the (read-only) ghostel buffer — the common semi-char case. The live-terminal path writes nothing to the buffer; it pastes over the PTY (point movement is allowed in a read-only buffer), so the guard is wrong. The fall-through to evil-paste-* still fails on its own insert when not driving the terminal. The existing test called the command directly, bypassing the interactive spec; add one that drives it through call-interactively in a read-only buffer.
dakra
force-pushed
the
evil-anchor-inhibit-hook
branch
from
June 30, 2026 15:15
5bf2290 to
41ce0f6
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Resolves #454. Under evil + an animated (~30 fps) terminal, ghostel's per-redraw
viewport anchor snapped point to the live terminal cursor on every frame, fighting
two interactions:
hjklmotion off the live cursor was yanked back ~30×/sec.Changes
Core (
ghostel.el)ghostel-anchor-inhibit-functionsabnormal hook (mirrorsghostel-inhibit-redraw-functions): a non-nil return from any function skips anchoring that window — neither viewport nor point moves — for the redraw. FORCE anchors (paste/yank, mode switches) still win. This is the blessed extension point asked for in the issue, replacing the brittledefine-adviceworkaround.ghostel-semi-char-mode/ghostel-char-modeanchors now pass FORCE, so an explicit mode switch always snaps back to the prompt even mid-roam.evil-ghostel
evil-ghostel--anchor-inhibit) that vetoes the anchor while point roams off the cursor in a motion-capable evil state, scoped to where evil-ghostel drives PTY input (evil-ghostel--active-p: semi-char, outside alt-screen) — so line/copy/emacs/alt-screen keep ghostel's own anchor handling.evil-ghostel--around-redrawnow only re-syncs to the live cursor while the window still tracks live output, so scrolling into scrollback sticks instead of being yanked back every frame.*) onp/P: paste is sent over the PTY and writes nothing to the read-only buffer, so the guard wrongly errored "Buffer is read-only" in the common semi-char case (separate pre-existing bug found while testing; the fall-through toevil-paste-*still fails on its own when not driving the terminal).Testing
p/Pon a read-only buffer (the existing paste test called the command directly and missed the interactive*barf).make allgreen.