Merge pull request #23874 from neovim/backport-23873-to-release-0.9

[Backport release-0.9] vim-patch:9.0.1597: cursor ends up below the window after a put
This commit is contained in:
zeertzjq
2023-06-02 09:00:13 +08:00
committed by GitHub
5 changed files with 55 additions and 5 deletions

View File

@@ -6185,6 +6185,10 @@ pos_T *var2fpos(const typval_T *const tv, const bool dollar_lnum, int *const ret
pos.coladd = 0; pos.coladd = 0;
if (name[0] == 'w' && dollar_lnum) { 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; pos.col = 0;
if (name[1] == '0') { // "w0": first visible line if (name[1] == '0') { // "w0": first visible line
update_topline(curwin); update_topline(curwin);

View File

@@ -441,18 +441,20 @@ void set_topline(win_T *wp, linenr_T lnum)
redraw_later(wp, UPD_VALID); redraw_later(wp, UPD_VALID);
} }
// Call this function when the length of the cursor line (in screen /// Call this function when the length of the cursor line (in screen
// characters) has changed, and the change is before the cursor. /// characters) has changed, and the change is before the cursor.
// Need to take care of w_botline separately! /// 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) 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); |VALID_CHEIGHT|VALID_TOPLINE);
} }
void changed_cline_bef_curs_win(win_T *wp) 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); |VALID_CHEIGHT|VALID_TOPLINE);
} }

View File

@@ -3490,6 +3490,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
if (lnum == curwin->w_cursor.lnum) { if (lnum == curwin->w_cursor.lnum) {
// make sure curwin->w_virtcol is updated // make sure curwin->w_virtcol is updated
changed_cline_bef_curs(); changed_cline_bef_curs();
invalidate_botline();
curwin->w_cursor.col += (colnr_T)(totlen - 1); curwin->w_cursor.col += (colnr_T)(totlen - 1);
} }
changed_bytes(lnum, col); changed_bytes(lnum, col);

View File

@@ -70,4 +70,29 @@ describe('put', function()
| |
]]) ]])
end) 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) end)

View File

@@ -266,5 +266,23 @@ func Test_put_other_window()
call VerifyScreenDump(buf, 'Test_put_other_window_1', {}) call VerifyScreenDump(buf, 'Test_put_other_window_1', {})
call StopVimInTerminal(buf) 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 endfunc