mirror of
https://github.com/neovim/neovim.git
synced 2025-09-05 19:08:15 +00:00
vim-patch:9.0.1597: cursor ends up below the window after a put
Problem: Cursor ends up below the window after a put.
Solution: Mark w_crow and w_botline invalid when changing the cursor line.
(closes vim/vim#12465)
8509014add
Co-authored-by: Bram Moolenaar <Bram@vim.org>
This commit is contained in:
@@ -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);
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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)
|
||||
|
@@ -266,5 +266,23 @@ func Test_put_other_window()
|
||||
call VerifyScreenDump(buf, 'Test_put_other_window_1', {})
|
||||
|
||||
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
|
||||
|
||||
|
Reference in New Issue
Block a user