Fix evil-ghostel multi-line dd targeting the wrong line (#218)#222
Merged
Fix evil-ghostel multi-line dd targeting the wrong line (#218)#222
Conversation
ff4f984 to
85b1bd4
Compare
e08e132 to
4be599d
Compare
In multi-line TUI input (pi, ipython, prompt_toolkit), ESC k dd deleted the last line instead of the line at point. In a normal single-line shell, several operator and motion edge cases were also broken — flagged by noctuid in the #218 follow-up. User-visible fixes: - dd / cc on a non-cursor row in multi-line input deletes the right line. Line-type evil-delete / evil-change dispatches by viewport row: same-row keeps the readline Ctrl-e/Ctrl-u shortcut; off-row syncs the terminal cursor to end-of-region and backspaces through it. A one-shot sync-point-on-next-redraw lands point at the start of the input area after the Ctrl-u path, not at column 0 on the prompt. - cw on a word lands at the start of the deleted range, not at column 0. around-change no longer runs a redundant post-delete cursor-to-point that would emit extra left arrows against the stale live libghostty cursor — sync only when count = 0 (the C-at-EOL path); delete-region already syncs in count > 0. - dw on 'word ' deletes 5 chars, not 4 ('word word word' + ESC bbdw → 'word word', not 'word wword'). meaningful-length strips trailing whitespace only in multi-line ranges, where TUI input boxes paint padding past the user's input; single-line ranges treat trailing whitespace as real content. - 0 and ^ skip the shell prompt prefix. evil-beginning-of-line and evil-first-non-blank route through ghostel-beginning-of-input-or-line on rows carrying the ghostel-prompt property, so 0i lands typing at the input start and d0 / c0 don't try to delete the prompt characters. Falls through to the original motion on scrollback / output rows. - ^ / \$ / 0 followed by i lands insertion at the navigated column even when the buffer has scrollback. insert-state-entry compared point's *buffer* line to the cursor's *viewport* row, so any scrollback failed the same-row check and dropped into reset-cursor-point — silently undoing the user's navigation. Subtract scrollback before comparing. - Column navigation in normal state (^, \$, 0, h, l, …) survives idle redraws on the cursor's line. The on-prompt-line override let the renderer's cursor placement win whenever point shared the cursor's buffer line — true for every redraw in a single-line shell. Replace with a prompt-moved check: only override saved-point when the cursor actually scrolled to a new line. - evil-replace's paste count matches its delete count when meaningful-length strips trailing whitespace in multi-line ranges, so trailing whitespace stripped from one side isn't re-added by the other. Architectural fixes underneath: - cursor-to-point subtracts scrollback when computing buffer→ viewport row deltas — was sending arrows off into space in any session with scrollback. - evil-ghostel--shadow-cursor models the pending terminal cursor between PTY-bound key emits and their echo back through the redraw. Within a single advice call we may emit several key sequences before any are echoed; ghostel--cursor-position reflects the live libghostty state, which lags our queued keys, so a follow-up cursor-to-point would compute deltas from a stale baseline and over-correct. cursor-to-point and delete-region advance the shadow as keys are emitted; around-redraw and unmodelable operations (Ctrl-a/e/u/w/r/n/p, paste) reset it. Verified live: shell dd / cc clears input via Ctrl-u with point at start of input; pi 'AAA\\nBBB\\nCCC' + ESC kk dd leaves BBB and CCC with AAA gone; word word word + ESC bbdw leaves word word; 0i on a shell prompt lands typing at the input start. Tests: 78 evil-ghostel, all passing — covers each user-visible fix and the shadow cursor lifecycle. Fixes #218
4be599d to
7e5e9e5
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
Fixes #218 — in multi-line TUI input (pi, ipython, ptpython),
ESC k dddeleted the wrong line. Investigation surfaced four other latent bugs in the same code paths; bundled together since the user-visible fix doesn't work without them.dd/cc: keep the readline-aware Ctrl-e/Ctrl-u shortcut for the single-line shell case (where the buffer line includes the prompt prefix); use cursor-sync + backspaces only when point is on a different viewport row from the terminal cursor (the actual Evil multi-line issues in pi #218 case).evil-ghostel--cursor-to-point— previously off by exactly the scrollback line count.evil-replacecount consistency — paste and delete now both go throughevil-ghostel--meaningful-lengthso trailing whitespace stripped from one side isn't re-added by the other.Test plan
make test-evil— 56/56 pass, including 7 new tests covering each fix.dd/cc: input cleared via Ctrl-u, prompt preserved, point lands at start of input area.AAA\nBBB\nCCC+ ESCkk dd:AAAgone,BBBandCCCremain.