summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2023-06-01 19:27:08 +0100
committerBram Moolenaar <Bram@vim.org>2023-06-01 19:27:08 +0100
commit8509014adda188ee8bdf6a2e123fbf15a91b29d2 (patch)
tree122f7ac29f4939cf2b87916e72b9fcb92475f08c
parenteb43b7f0531bd13d15580b5c262a25d6a52a0823 (diff)
patch 9.0.1597: cursor ends up below the window after a putv9.0.1597
Problem: Cursor ends up below the window after a put. Solution: Mark w_crow and w_botline invalid when changing the cursor line. (closes #12465)
-rw-r--r--src/eval.c4
-rw-r--r--src/move.c6
-rw-r--r--src/register.c1
-rw-r--r--src/testdir/dumps/Test_put_in_last_displayed_line_1.dump10
-rw-r--r--src/testdir/test_put.vim18
-rw-r--r--src/version.c2
6 files changed, 39 insertions, 2 deletions
diff --git a/src/eval.c b/src/eval.c
index b8d954d6a2..89141bfe3e 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -6322,6 +6322,10 @@ var2fpos(
if (name[0] == 'w' && dollar_lnum)
{
+ // the "w_valid" flags are not reset when moving the cursor, but they
+ // do matter for update_topline() and validate_botline().
+ check_cursor_moved(curwin);
+
pos.col = 0;
if (name[1] == '0') // "w0": first visible line
{
diff --git a/src/move.c b/src/move.c
index e435bb08bb..a1139199e6 100644
--- a/src/move.c
+++ b/src/move.c
@@ -715,19 +715,21 @@ set_topline(win_T *wp, linenr_T lnum)
/*
* Call this function when the length of the cursor line (in screen
* characters) has changed, and the change is before the cursor.
+ * If the line length changed the number of screen lines might change,
+ * requiring updating w_topline. That may also invalidate w_crow.
* Need to take care of w_botline separately!
*/
void
changed_cline_bef_curs(void)
{
- curwin->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL
+ curwin->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL|VALID_CROW
|VALID_CHEIGHT|VALID_TOPLINE);
}
void
changed_cline_bef_curs_win(win_T *wp)
{
- wp->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL
+ wp->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL|VALID_CROW
|VALID_CHEIGHT|VALID_TOPLINE);
}
diff --git a/src/register.c b/src/register.c
index e481d843c2..9a23be8592 100644
--- a/src/register.c
+++ b/src/register.c
@@ -2098,6 +2098,7 @@ do_put(
{
// make sure curwin->w_virtcol is updated
changed_cline_bef_curs();
+ invalidate_botline();
curwin->w_cursor.col += (colnr_T)(totlen - 1);
}
if (VIsual_active)
diff --git a/src/testdir/dumps/Test_put_in_last_displayed_line_1.dump b/src/testdir/dumps/Test_put_in_last_displayed_line_1.dump
new file mode 100644
index 0000000000..3d094f5522
--- /dev/null
+++ b/src/testdir/dumps/Test_put_in_last_displayed_line_1.dump
@@ -0,0 +1,10 @@
+|2+0&#ffffff0| @73
+|3| @73
+|4| @73
+|5| @73
+|6| @73
+|7| @73
+|8| @73
+|9|x@73
+@73>x|
+@57|1|0|,|1|4|9| @7|B|o|t|
diff --git a/src/testdir/test_put.vim b/src/testdir/test_put.vim
index 4b514bb754..72479ac7d4 100644
--- a/src/testdir/test_put.vim
+++ b/src/testdir/test_put.vim
@@ -262,5 +262,23 @@ func Test_put_other_window()
call StopVimInTerminal(buf)
endfunc
+func Test_put_in_last_displayed_line()
+ CheckRunVimInTerminal
+
+ let lines =<< trim END
+ vim9script
+ autocmd CursorMoved * eval line('w$')
+ @a = 'x'->repeat(&columns * 2 - 2)
+ range(&lines)->setline(1)
+ feedkeys('G"ap')
+ END
+ call writefile(lines, 'Xtest_put_last_line', 'D')
+ let buf = RunVimInTerminal('-S Xtest_put_last_line', #{rows: 10})
+
+ call VerifyScreenDump(buf, 'Test_put_in_last_displayed_line_1', {})
+
+ call StopVimInTerminal(buf)
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index 132a0d96f9..11b962d7e0 100644
--- 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 */
/**/
+ 1597,
+/**/
1596,
/**/
1595,