diff options
-rw-r--r-- | src/nvim/eval.c | 4 | ||||
-rw-r--r-- | src/nvim/move.c | 12 | ||||
-rw-r--r-- | src/nvim/ops.c | 1 | ||||
-rw-r--r-- | test/functional/legacy/put_spec.lua | 25 | ||||
-rw-r--r-- | test/old/testdir/test_put.vim | 18 |
5 files changed, 55 insertions, 5 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 52924bf9a5..118c1d3012 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -6511,6 +6511,10 @@ pos_T *var2fpos(const typval_T *const tv, const bool dollar_lnum, int *const ret pos.coladd = 0; 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 update_topline(curwin); diff --git a/src/nvim/move.c b/src/nvim/move.c index 9e8abbcd96..48691db26d 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -548,18 +548,20 @@ void set_topline(win_T *wp, linenr_T lnum) redraw_later(wp, UPD_VALID); } -// Call this function when the length of the cursor line (in screen -// characters) has changed, and the change is before the cursor. -// Need to take care of w_botline separately! +/// 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/nvim/ops.c b/src/nvim/ops.c index c39a3273da..2711c3d29c 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -3484,6 +3484,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) if (lnum == curwin->w_cursor.lnum) { // make sure curwin->w_virtcol is updated changed_cline_bef_curs(); + invalidate_botline(); curwin->w_cursor.col += (colnr_T)(totlen - 1); } changed_bytes(lnum, col); diff --git a/test/functional/legacy/put_spec.lua b/test/functional/legacy/put_spec.lua index e83fde774a..4a42a1c8a3 100644 --- a/test/functional/legacy/put_spec.lua +++ b/test/functional/legacy/put_spec.lua @@ -70,4 +70,29 @@ describe('put', function() | ]]) end) + + -- oldtest: Test_put_in_last_displayed_line() + it('in last displayed line', function() + local screen = Screen.new(75, 10) + screen:attach() + source([[ + autocmd CursorMoved * eval line('w$') + let @a = 'x'->repeat(&columns * 2 - 2) + eval range(&lines)->setline(1) + call feedkeys('G"ap') + ]]) + + screen:expect([[ + 2 | + 3 | + 4 | + 5 | + 6 | + 7 | + 8 | + 9xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx| + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx^x | + | + ]]) + end) end) diff --git a/test/old/testdir/test_put.vim b/test/old/testdir/test_put.vim index 212a979b4a..6c4bd28386 100644 --- a/test/old/testdir/test_put.vim +++ b/test/old/testdir/test_put.vim @@ -266,5 +266,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 |