mirror of
https://github.com/neovim/neovim.git
synced 2025-10-06 01:46:29 +00:00
Fix shift change callbacks reading bad cursor (#11782)
Sloppy code inherited from Vim caused user scripts to be able to observe the cursor line in an invalid intermediary state, due to Neovim change callbacks being unbuffered unlike Vim listeners. Manifested in Vimscript executed from the callback possibly erroring when `:call`:ing any function, due to the implicit range `curwin->w_cursor.lnum,curwin->w_cursor.lnum` failing validation. Fixed by deferring the call to `changed_lines()` until after `curwin->w_cursor.lnum` gets its correct value.
This commit is contained in:
@@ -221,8 +221,6 @@ void op_shift(oparg_T *oap, int curs_top, int amount)
|
||||
++curwin->w_cursor.lnum;
|
||||
}
|
||||
|
||||
changed_lines(oap->start.lnum, 0, oap->end.lnum + 1, 0L, true);
|
||||
|
||||
if (oap->motion_type == kMTBlockWise) {
|
||||
curwin->w_cursor.lnum = oap->start.lnum;
|
||||
curwin->w_cursor.col = block_col;
|
||||
@@ -262,8 +260,11 @@ void op_shift(oparg_T *oap, int curs_top, int amount)
|
||||
curbuf->b_op_start = oap->start;
|
||||
curbuf->b_op_end.lnum = oap->end.lnum;
|
||||
curbuf->b_op_end.col = (colnr_T)STRLEN(ml_get(oap->end.lnum));
|
||||
if (curbuf->b_op_end.col > 0)
|
||||
--curbuf->b_op_end.col;
|
||||
if (curbuf->b_op_end.col > 0) {
|
||||
curbuf->b_op_end.col--;
|
||||
}
|
||||
|
||||
changed_lines(oap->start.lnum, 0, oap->end.lnum + 1, 0L, true);
|
||||
}
|
||||
|
||||
// Shift the current line one shiftwidth left (if left != 0) or right
|
||||
|
@@ -203,4 +203,17 @@ describe('lua: buffer event callbacks', function()
|
||||
{ "test1", "lines", 1, tick+1, 5, 6, 5, 27, 20, 20 }}, exec_lua("return get_events(...)" ))
|
||||
end)
|
||||
|
||||
it('has valid cursor position while shifting', function()
|
||||
meths.buf_set_lines(0, 0, -1, true, {'line1'})
|
||||
exec_lua([[
|
||||
vim.api.nvim_buf_attach(0, false, {
|
||||
on_lines = function()
|
||||
vim.api.nvim_set_var('listener_cursor_line', vim.api.nvim_win_get_cursor(0)[1])
|
||||
end,
|
||||
})
|
||||
]])
|
||||
feed('>>')
|
||||
eq(1, meths.get_var('listener_cursor_line'))
|
||||
end)
|
||||
|
||||
end)
|
||||
|
Reference in New Issue
Block a user