From 7fe3ea7658a1f3be4e07dee14041302ca129c8a9 Mon Sep 17 00:00:00 2001 From: Hirohito Higashi Date: Thu, 30 Jul 2026 19:28:04 +0000 Subject: [PATCH] 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: #12085 closes: #20884 Co-Authored-By: Claude Opus 5 (1M context) Signed-off-by: Hirohito Higashi Signed-off-by: Christian Brabandt --- runtime/doc/todo.txt | 10 +++++----- src/misc1.c | 5 +++-- src/testdir/test_window_cmd.vim | 18 ++++++++++++++++++ src/version.c | 2 ++ 4 files changed, 28 insertions(+), 7 deletions(-) diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt index f265b39689..9c8c0f4933 100644 --- a/runtime/doc/todo.txt +++ b/runtime/doc/todo.txt @@ -1,4 +1,4 @@ -*todo.txt* For Vim version 9.2. Last change: 2026 Jun 23 +*todo.txt* For Vim version 9.2. Last change: 2026 Jul 30 VIM REFERENCE MANUAL by Bram Moolenaar @@ -40,10 +40,10 @@ Mapping with modifier is not recognized after a partial mapping. Probably because the typeahead was simplified when looking for a matching mapping. Need to somehow undo the simplification. #12002 -Windows scroll when using the autocmd window. #12085 -in restore_snapshot_rec() restore more values from the snapshot, instead of -calling frame_new_height() and frame_new_width(), especially w_topline and -w_skipcol. +Using the autocmd window resets w_skipcol when the cursor is in a long +wrapped line. In restore_snapshot_rec() restore more values from the +snapshot, instead of calling frame_new_height() and frame_new_width(), +especially w_skipcol. Check places that source "path/*.vim" to not match other extensions, e.g. .vim9, on MS-Windows (short file name match, gets expanded to long file name). diff --git a/src/misc1.c b/src/misc1.c index c09ae81275..6ba215500d 100644 --- a/src/misc1.c +++ b/src/misc1.c @@ -439,7 +439,7 @@ 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) @@ -465,7 +465,8 @@ plines_win_col(win_T *wp, linenr_T lnum, long column) line = ml_get_buf(wp->w_buffer, lnum, FALSE); init_chartabsize_arg(&cts, wp, lnum, 0, line, line); - while (*cts.cts_ptr != NUL && --column >= 0) + // "column" is a byte index, advance the pointer until it is reached. + while (*cts.cts_ptr != NUL && cts.cts_ptr < line + column) { cts.cts_vcol += win_lbr_chartabsize(&cts, NULL, NULL); MB_PTR_ADV(cts.cts_ptr); diff --git a/src/testdir/test_window_cmd.vim b/src/testdir/test_window_cmd.vim index bf524030f9..701eec65c4 100644 --- a/src/testdir/test_window_cmd.vim +++ b/src/testdir/test_window_cmd.vim @@ -2034,6 +2034,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 diff --git a/src/version.c b/src/version.c index 5bc24b40a0..caef0f750a 100644 --- a/src/version.c +++ b/src/version.c @@ -758,6 +758,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 880, /**/ 879, /**/ -- 2.47.3