Problem: Virtual text breaks cursor movement when virtualtext=all is set.
Solution: Take screen space occupied by virtual text into account when calculating the cursor position with virtualtext=all enabled.
Virtual text can be displayed above, after or below buffer text. While buffer text exists in both file space (text which is part of the file or buffer) and screen space (text which is shown to the user), virtual text only exists in screen space.
With virtualedit=none (the default) the cursor may only move over buffer text. When the representation of buffer text differs between file and screen space, these differences must be taking into account when calculating the cursor position. Examples are tab length, concealed text, etc.
Since virtual text never overlays buffer text, assumptions can be made when calculating cursor positions on lines with virtual text: Virtual text after buffer text can never be reached, virtual text above or below buffer text add an extra line to screen space which can be skipped.
Setting virtualedit=all allows the cursor to move over the full screen space, breaking these assumptions. Virtual text above buffer text is represented by characters and padding left to the cursor, virtual text after or below buffer text as characters and padding right to the cursor. The line consisting of virtual text and buffer text is wrapped to give the impression of one or more "virtual" linies above or below the buffer text. The cursor may move onto all screen space cells in display lines with buffer text, even if these are occupied by virtual text. It may not move into "virtual" display lines.
To archive the later the cells occupied by virtual text left to the cursor are ignored when calculating the cursor position and cells to the right are taken into account when calculating the end of line position. There were two bugs with this logic:
GETVCOL_NO_ABOVE to getviscol(). When set, the cursor position is returned wirh virtual text excluded. This additionally enables the removal of a hack in coladvance2() trying to work around a part of the underlying problem.coladvance2() calculates the length of the current line with linetabsize_eol() which included all virtual text right to the cursor. Therefor it is possible to move into the "virtual" line below the buffer text line. When moving vertically from the EOL position, the length of the virtual text right to the cursor is added to the cursor movement. Both problems were fixed by implementing another Variante of linetabsize - linetabsize_no_outer_eol() - which excludes surrounding virtual text.fixes: #14049
AI disclosure: Claude Code was used to analyze the problem and draft a patch. The final patch was developed and tested by hand.
https://github.com/vim/vim/pull/21336
(6 files)
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.![]()
Aren't the PR description and code comments a bit redundant? There's no need to explain things that are obvious just by looking at the code.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.![]()