Rewrite evil-ghostel from advice to command-remap architecture#264
Rewrite evil-ghostel from advice to command-remap architecture#264dakra wants to merge 1 commit into
Conversation
|
@dakra Thanks a lot. I didn't have time to test thoroughly. I'll test tomorrow but couldn't find any major problems with basic use. Here are two things:
|
872b853 to
fc7f17f
Compare
|
@noctuid Thanks. I fixed the 2 bugs you mentioned. |
fc7f17f to
4228dc0
Compare
|
I still haven't seen any more issues with editing/operators, though I'm seeing similar issues to the appending one. Sometimes the cursor will jump to the right side of the window when appending.
I saw weird point warping a couple of times but can't reliably reproduce. |
4ee9cd4 to
310826b
Compare
|
Tested on aarch64-darwin, emacs 30, doom/evil latest with fish. Basic nav seems to be working. I have the git branch justified right like: ~/.c/doom ❯❯❯ nslookup -type=txt on.quad9.net 2620:fe::9 main ✱
When I move out of a git repo, the ~ ❯❯❯ nslookup -type=txt on.quad9.net 2620:fe::9These bugs do not persist. |
|
Is this intended to fix insert at cursor problems as well? Currently:
Also given |
310826b to
e446072
Compare
Replaces ~13 advice-add hooks on evil-* commands with proper evil-define-operator / evil-define-motion definitions bound via evil-ghostel-mode-map for normal and visual states. New evil-ghostel commands: -delete (and -line/-char/-backward-char), -change (and -line), -substitute (and -line), -replace, -paste-after, -paste-before, -insert (and -line), -append (and -line), -beginning-of-line, -first-non-blank, -forward-word-begin/-WORD-begin/-word-end/-WORD-end, -undo, -redo. Bound in evil-ghostel-mode-map; forward-word motions are normal-only so operator-pending (dw, cw) uses vanilla motion + operator clamp. Drops the shadow-cursor model and all advice on evil-* commands. Keeps advice on `ghostel--redraw' / `ghostel--set-cursor-style' and the insert-state-entry hook (essential plumbing). Those two advice-add calls install on first mode-enable and are removed only when the LAST `evil-ghostel-mode' buffer disables — otherwise toggling off in one buffer would silently strip the wrapper from every other ghostel buffer. PTY-driven input editing helpers (new, live here because they all depend on a cooperative line editor — readline / zle / prompt_toolkit accepting arrow keys, backspace, bracketed paste): - evil-ghostel-goto-input-position — moves the terminal cursor via arrow keys, with vterm-style recovery for literal `^[[C' echo and bash-autosuggest accept-on-right-arrow. - evil-ghostel-delete-input-region, -replace-input-region. - evil-ghostel-point-in-input-p — predicate for the editable input region. - evil-ghostel--clamp-to-input — trims an operator's range to the live input region. Clamps END to row-end on forward overshoot so `dw' on the last input word no longer over-deletes into blank renderer rows below the prompt. - evil-ghostel--cursor-row-end-point — end of typed input on the cursor row. Returns the end of the FIRST contiguous `ghostel-input' region (so fish's right-aligned prompt — which libghostty's per-cell heuristic also tags SEMANTIC_INPUT despite no OSC 133;B emission — is ignored, issue #264), with a whitespace-gap fallback (`evil-ghostel-right-prompt-gap', default 6) when no `ghostel-input' cells are on the row. `i' / `a' / `I' / `A' / `$' / `y$' clamp to this, so RPROMPT and zsh-autosuggest hint cells cannot capture the cursor. - evil-ghostel--input-start-from-prop, --meaningful-input-length, --sync-render — internal helpers. `--sync-render' loops the PTY drain (capped via `evil-ghostel-sync-render-max-iterations') and force-runs `ghostel--delayed-redraw' when the filter deferred a bulk-output redraw, so callers reading `ghostel--cursor-pos' after large echoes (100+ backspaces in `cc' / `cw') see post-drain state instead of stale values. Tests: 113 evil-ghostel tests covering operators, motions, paste, undo/redo, escape handling, plus unit tests for the new input-region helpers, the advice lifecycle, and the sync-render forced-redraw path.
e446072 to
b5378fb
Compare
|
I experimented a bit with different versions today. But in my short testing it seems to work now. |
|
@dakra Is this PR being canceled or replaced? |
|
@noctuid oh. I was doing some housekeeping in magit of git-refs and deleted a bunch of old branches. |
|
None of these are fixed: |
|
Also a weird one: typing |
Replaces ~13 advice-add hooks on evil-* commands with proper evil-define-operator / evil-define-motion definitions bound via evil-ghostel-mode-map for normal and visual states. New evil-ghostel commands: -delete (and -line/-char/-backward-char), -change (and -line), -substitute (and -line), -replace, -paste-after, -paste-before, -insert (and -line), -append (and -line), -beginning-of-line, -first-non-blank, -forward-word-begin/-WORD-begin/-word-end/-WORD-end, -undo, -redo. Bound in evil-ghostel-mode-map; forward-word motions are normal-only so operator-pending (dw, cw) uses vanilla motion + operator clamp. Drops the shadow-cursor model and all advice on evil-* commands. Keeps advice on `ghostel--redraw' / `ghostel--set-cursor-style' and the insert-state-entry hook (essential plumbing). Those two advice-add calls install on first mode-enable and are removed only when the LAST `evil-ghostel-mode' buffer disables — otherwise toggling off in one buffer would silently strip the wrapper from every other ghostel buffer. PTY-driven input editing helpers (new, live here because they all depend on a cooperative line editor — readline / zle / prompt_toolkit accepting arrow keys, backspace, bracketed paste): - evil-ghostel-goto-input-position — moves the terminal cursor via arrow keys, with vterm-style recovery for literal `^[[C' echo and bash-autosuggest accept-on-right-arrow. - evil-ghostel-delete-input-region, -replace-input-region. - evil-ghostel-point-in-input-p — predicate for the editable input region. - evil-ghostel--clamp-to-input — trims an operator's range to the live input region. Clamps END to row-end on forward overshoot so `dw' on the last input word no longer over-deletes into blank renderer rows below the prompt. - evil-ghostel--cursor-row-end-point — end of typed input on the cursor row. Returns the end of the FIRST contiguous `ghostel-input' region (so fish's right-aligned prompt — which libghostty's per-cell heuristic also tags SEMANTIC_INPUT despite no OSC 133;B emission — is ignored, issue #264), with a whitespace-gap fallback (`evil-ghostel-right-prompt-gap', default 6) when no `ghostel-input' cells are on the row. `i' / `a' / `I' / `A' / `$' / `y$' clamp to this, so RPROMPT and zsh-autosuggest hint cells cannot capture the cursor. - evil-ghostel--input-start-from-prop, --meaningful-input-length, --sync-render — internal helpers. `--sync-render' loops the PTY drain (capped via `evil-ghostel-sync-render-max-iterations') and force-runs `ghostel--delayed-redraw' when the filter deferred a bulk-output redraw, so callers reading `ghostel--cursor-pos' after large echoes (100+ backspaces in `cc' / `cw') see post-drain state instead of stale values. Tests: 113 evil-ghostel tests covering operators, motions, paste, undo/redo, escape handling, plus unit tests for the new input-region helpers, the advice lifecycle, and the sync-render forced-redraw path.
b5378fb to
3994f6b
Compare
that works for me.
Do you have shell integration on? |
Summary
advice-addhooks onevil-*commands withevil-define-operator/evil-define-motiondefinitions bound viaevil-ghostel-mode-mapfor normal and visual states (vterm-collection-style).ghostel.el(ghostel-input-start-point,ghostel-cursor-point,ghostel-cursor-row-end-point,ghostel-point-on-cursor-row-p,ghostel-point-in-input-p,ghostel-clamp-to-input,ghostel-goto-input-position,ghostel-delete-input-region,ghostel-replace-input-region) that integrations can build on. Lifts what was internalevil-ghostel--cursor-to-point/--delete-region/--meaningful-lengthinto ghostel core.ghostel--cursor-posdirectly each call and the existingsync-inhibitflag already covers the double-call scenarios the shadow was defending against.dwon the last input word no longer over-deletes into the blank renderer rows below the prompt. End-of-typed-input is detected by stripping trailing whitespace on the cursor row; works for shells without OSC 133.w,W,e,E) clamped in normal state only sowfrom the last input word stays on the cursor row. Operator-pending state uses vanilla motions sodw/cwranges can overshoot and get trimmed by the operator clamp.ghostel-goto-input-positionincludes vterm-style recovery for literal^[[Cecho (inner program doesn't interpret arrow keys) and for bash-autosuggest accept-on-right-arrow.Test plan
make -j4 all test-evilclean: 370 elisp + 173 native + 76 evil-ghostel tests, 0 unexpected, 2 unrelated skips, lint clean.evil-ghostel-test-delete-word-on-last-word-clamps-overshoot), w-stays-on-input-row (evil-ghostel-test-forward-word-stops-at-input-end), w-falls-through-in-scrollback (evil-ghostel-test-forward-word-falls-through-off-cursor-row).Emacs -Qagainstzsh -fi(no OSC 133):word word word<esc>bbcw→ correct,wstays on cursor row,dwon last word deletes it,0/^/$work.bbcw3× consecutively in zsh and pi to confirm no regressions.Notes for reviewers
evil-ghostel.elends up at 852 LOC vs evil-collection-vterm's 308. The delta is dominated byevil-ghostel--around-redraw(79 LOC — ghostel's renderer wipes the viewport region, vterm doesn't need this), the cursor↔point sync helpers (~50 LOC — viewport-row math), the insert-state-entry hook (45 LOC — vterm's cursor is the buffer cursor), and the three-way ESC routing (auto/terminal/evil).ghostel-*input-region functions become public contract.