# HG changeset patch # User Christian Brabandt # Date 1692558003 -7200 # Node ID 41482b74f548469a0982b9183aab737f8abd1c9d # Parent 2ff007677dba3872f802d54cb6c8d32885e12d1c patch 9.0.1772: Cursor may be adjusted in 'splitkeep'ed windows Commit: https://github.com/vim/vim/commit/16af913eeefb288ce968fb87e09a597413861900 Author: Luuk van Baal Date: Sun Aug 20 20:44:59 2023 +0200 patch 9.0.1772: Cursor may be adjusted in 'splitkeep'ed windows Problem: Cursor is adjusted in window that did not change in size by 'splitkeep'. Solution: Only check that cursor position is valid in a window that has changed in size. closes: #12509 Signed-off-by: Christian Brabandt Co-authored-by: Luuk van Baal diff --git a/src/structs.h b/src/structs.h --- a/src/structs.h +++ b/src/structs.h @@ -3778,6 +3778,7 @@ struct window_S int w_vsep_width; // Number of separator columns (0 or 1). pos_save_T w_save_cursor; // backup of cursor pos and topline + int w_do_win_fix_cursor;// if TRUE cursor may be invalid #ifdef FEAT_PROP_POPUP int w_popup_flags; // POPF_ values diff --git a/src/testdir/dumps/Test_splitkeep_cursor_1.dump b/src/testdir/dumps/Test_splitkeep_cursor_1.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_splitkeep_cursor_1.dump @@ -0,0 +1,8 @@ +|9+0&#ffffff0@1| @72 +>1|0@1| @71 +|1|0|1| @71 +|[+3&&|N|o| |N|a|m|e|]| |[|+|]| @43|1|0@1|,|1| @9|4|9|% +|5+0&&| @73 +|6| @73 +|[+1&&|N|o| |N|a|m|e|]| |[|+|]| @43|5|,|1| @12|2|% +| +0&&@74 diff --git a/src/testdir/dumps/Test_splitkeep_cursor_2.dump b/src/testdir/dumps/Test_splitkeep_cursor_2.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_splitkeep_cursor_2.dump @@ -0,0 +1,8 @@ +|1+0&#ffffff0|0@1| @71 +>1|0|1| @71 +|1|0|2| @71 +|[+3&&|N|o| |N|a|m|e|]| |[|+|]| @43|1|0|1|,|1| @9|5|0|% +|5+0&&| @73 +|6| @73 +|[+1&&|N|o| |N|a|m|e|]| |[|+|]| @43|5|,|1| @12|2|% +| +0&&@74 diff --git a/src/testdir/dumps/Test_splitkeep_cursor_3.dump b/src/testdir/dumps/Test_splitkeep_cursor_3.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_splitkeep_cursor_3.dump @@ -0,0 +1,8 @@ +|1+0&#ffffff0|9|8| @71 +|1|9@1| @71 +>2|0@1| @71 +|[+3&&|N|o| |N|a|m|e|]| |[|+|]| @43|2|0@1|,|1| @9|B|o|t +|5+0&&| @73 +|6| @73 +|[+1&&|N|o| |N|a|m|e|]| |[|+|]| @43|5|,|1| @12|2|% +|:+0&&|s|e|t| |s|c|r|o|l@1|o|f@1|=|0| @58 diff --git a/src/testdir/test_window_cmd.vim b/src/testdir/test_window_cmd.vim --- a/src/testdir/test_window_cmd.vim +++ b/src/testdir/test_window_cmd.vim @@ -1861,6 +1861,33 @@ func Test_splitkeep_misc() set splitkeep& endfunc +func Test_splitkeep_cursor() + CheckScreendump + let lines =<< trim END + set splitkeep=screen + autocmd CursorMoved * wincmd p | wincmd p + call setline(1, range(1, 200)) + func CursorEqualize() + call cursor(100, 1) + wincmd = + endfunc + wincmd s + call CursorEqualize() + END + call writefile(lines, 'XTestSplitkeepCallback', 'D') + let buf = RunVimInTerminal('-S XTestSplitkeepCallback', #{rows: 8}) + + call VerifyScreenDump(buf, 'Test_splitkeep_cursor_1', {}) + + call term_sendkeys(buf, "j") + call VerifyScreenDump(buf, 'Test_splitkeep_cursor_2', {}) + + call term_sendkeys(buf, ":set scrolloff=0\G") + call VerifyScreenDump(buf, 'Test_splitkeep_cursor_3', {}) + + call StopVimInTerminal(buf) +endfunc + func Test_splitkeep_callback() CheckScreendump let lines =<< trim END diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -696,6 +696,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1772, +/**/ 1771, /**/ 1770, diff --git a/src/window.c b/src/window.c --- a/src/window.c +++ b/src/window.c @@ -6789,6 +6789,10 @@ win_fix_scroll(int resize) // Skip when window height has not changed. if (wp->w_height != wp->w_prev_height) { + // Cursor position in this window may now be invalid. It is kept + // potentially invalid until the window is made the current window. + wp->w_do_win_fix_cursor = TRUE; + // If window has moved update botline to keep the same screenlines. if (*p_spk == 's' && wp->w_winrow != wp->w_prev_winrow && wp->w_botline - 1 <= wp->w_buffer->b_ml.ml_line_count) @@ -6813,6 +6817,7 @@ win_fix_scroll(int resize) } else if (wp == curwin) wp->w_valid &= ~VALID_CROW; + invalidate_botline_win(wp); validate_botline_win(wp); } @@ -6830,7 +6835,7 @@ win_fix_scroll(int resize) /* * Make sure the cursor position is valid for 'splitkeep'. * If it is not, put the cursor position in the jumplist and move it. - * If we are not in normal mode ("normal" is zero), make it valid by scrolling + * If we are not in normal mode ("normal" is FALSE), make it valid by scrolling * instead. */ static void @@ -6838,9 +6843,12 @@ win_fix_cursor(int normal) { win_T *wp = curwin; - if (skip_win_fix_cursor || wp->w_buffer->b_ml.ml_line_count < wp->w_height) + if (skip_win_fix_cursor + || !wp->w_do_win_fix_cursor + || wp->w_buffer->b_ml.ml_line_count < wp->w_height) return; + wp->w_do_win_fix_cursor = FALSE; // Determine valid cursor range. long so = MIN(wp->w_height / 2, get_scrolloff_value()); linenr_T lnum = wp->w_cursor.lnum; @@ -6873,7 +6881,7 @@ win_fix_cursor(int normal) { wp->w_fraction = (nlnum == bot) ? FRACTION_MULT : 0; scroll_to_fraction(wp, wp->w_prev_height); - validate_botline_win(curwin); + validate_botline(); } } }