aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAxel Forsman <axelsfor@gmail.com>2020-01-30 07:34:34 +0100
committerGitHub <noreply@github.com>2020-01-30 07:34:34 +0100
commit2538e615130c7f4baa1029d0be2bc2d7f66cdd7e (patch)
treea8a137e31418582f7c714ab7356ba850ebe233a2
parent4ea5d7d31a0ad43a84d268e6b05193fa27c5e0da (diff)
downloadrneovim-2538e615130c7f4baa1029d0be2bc2d7f66cdd7e.tar.gz
rneovim-2538e615130c7f4baa1029d0be2bc2d7f66cdd7e.tar.bz2
rneovim-2538e615130c7f4baa1029d0be2bc2d7f66cdd7e.zip
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.
-rw-r--r--src/nvim/ops.c9
-rw-r--r--test/functional/lua/buffer_updates_spec.lua13
2 files changed, 18 insertions, 4 deletions
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index db5c98ed78..6d327c0814 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -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
diff --git a/test/functional/lua/buffer_updates_spec.lua b/test/functional/lua/buffer_updates_spec.lua
index 990cb97fec..7d3ecbf912 100644
--- a/test/functional/lua/buffer_updates_spec.lua
+++ b/test/functional/lua/buffer_updates_spec.lua
@@ -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)