vim-patch:9.2.0880: scroll: window scrolls when using the autocommand window

Problem:  The window scrolls when an autocommand window is used while the
          cursor is behind multi-byte characters.
Solution: Use the byte column instead of the character count when computing
          how many screen lines the text up to the cursor takes.

fixes:  vim/vim#12085
closes: vim/vim#20884

7fe3ea7658

Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
zeertzjq
2026-07-31 10:50:57 +08:00
parent 9d7c004ade
commit f9040dbe03
2 changed files with 21 additions and 3 deletions

View File

@@ -814,7 +814,7 @@ int plines_win_nofold(win_T *wp, linenr_T lnum)
}
/// Like plines_win(), but only reports the number of physical screen lines
/// used from the start of the line to the given column number.
/// used from the start of the line to the given byte column.
int plines_win_col(win_T *wp, linenr_T lnum, long column)
{
// Check for filler lines above this buffer line.
@@ -837,12 +837,12 @@ int plines_win_col(win_T *wp, linenr_T lnum, long column)
StrCharInfo ci = utf_ptr2StrCharInfo(line);
if (cstype == kCharsizeFast) {
bool const use_tabstop = csarg.use_tabstop;
while (*ci.ptr != NUL && --column >= 0) {
while (*ci.ptr != NUL && ci.ptr < line + column) {
vcol += charsize_fast_impl(wp, ci.ptr, use_tabstop, vcol, ci.chr.value).width;
ci = utfc_next(ci);
}
} else {
while (*ci.ptr != NUL && --column >= 0) {
while (*ci.ptr != NUL && ci.ptr < line + column) {
vcol += charsize_regular(&csarg, ci.ptr, vcol, ci.chr.value).width;
ci = utfc_next(ci);
}

View File

@@ -1989,6 +1989,24 @@ func Test_splitkeep_cmdheight()
set splitkeep& cmdheight&
endfunc
func Test_aucmd_win_scroll_multibyte()
" Using the autocommand window must not scroll the current window when the
" cursor is behind multi-byte characters.
set splitkeep=cursor
call setline(1, repeat([repeat(nr2char(0x3042), 200)], 20))
normal! G0100l
redraw
let topline = line('w0')
for i in range(3)
call bufload(bufadd(''))
endfor
call assert_equal(topline, line('w0'))
%bwipeout!
set splitkeep&
endfunc
func Test_splitkeep_cursor()
CheckScreendump
let lines =<< trim END