Files
neovim/test
zeertzjq 318ea4de21 vim-patch:9.2.1054: Virtual Replace mode: BS over multi-byte text eats the padding (#41799)
Problem:  In Virtual Replace mode, backspacing over a character that
          replaced several multi-byte characters deletes the padding
          that follows it, so the text after the cursor loses its
          alignment.
Solution: In replace_do_bs() advance by the length of the character at
          the current offset instead of always measuring the first
          restored character (Volodymyr Chernetskyi).

After the original characters are restored, replace_do_bs() adds up
their screen width so it knows how much of the alignment padding to drop
again. The loop advanced "i" by mb_ptr2len(p) - 1, which always returns
the length of the *first* restored character rather than the length of
the character at the offset being looked at.

One backspace can restore more than one character, because a wide
character may have replaced several narrow ones.  When those characters
do not all have the same byte length the index lands in the middle of a
character: chartabsize() then measures a trailing byte, counts it as an
unprintable <xx> worth four cells, and the inflated width makes the
following loop delete padding spaces that should have been kept.

    call setline(1, 'aé    xyz')
    call feedkeys("gR\u4e00\<BS>\e", 'xt')

leaves "aéxyz" instead of restoring the original line.  Going the other
way round ('éa') happens to work, since there the first character is the
longer one.

This has been wrong since the loop was added in Vim 7.0.

closes: vim/vim#21211

5d934b1bdb

Co-authored-by: Volodymyr Chernetskyi <19735328+chernetskyi@users.noreply.github.com>
2026-09-09 01:22:54 +00:00
..
2026-04-22 18:25:07 -04:00