diff options
-rw-r--r-- | src/nvim/ops.c | 9 | ||||
-rw-r--r-- | test/functional/lua/buffer_updates_spec.lua | 55 |
2 files changed, 62 insertions, 2 deletions
diff --git a/src/nvim/ops.c b/src/nvim/ops.c index d1f2e9e4f1..8329daf5f1 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -3109,6 +3109,9 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) for (i = 0; i < y_size; i++) { int spaces; char shortline; + // can just be 0 or 1, needed for blockwise paste beyond the current + // buffer end + int lines_appended = 0; bd.startspaces = 0; bd.endspaces = 0; @@ -3122,6 +3125,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) break; } nr_lines++; + lines_appended = 1; } /* get the old line and advance to the position to insert at */ oldp = get_cursor_line_ptr(); @@ -3194,14 +3198,15 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) memmove(ptr, oldp + bd.textcol + delcount, (size_t)columns); ml_replace(curwin->w_cursor.lnum, newp, false); extmark_splice_cols(curbuf, (int)curwin->w_cursor.lnum-1, bd.textcol, - delcount, (int)totlen, kExtmarkUndo); + delcount, (int)totlen + lines_appended, kExtmarkUndo); ++curwin->w_cursor.lnum; if (i == 0) curwin->w_cursor.col += bd.startspaces; } - changed_lines(lnum, 0, curwin->w_cursor.lnum, nr_lines, true); + changed_lines(lnum, 0, curbuf->b_op_start.lnum + (linenr_T)y_size + - (linenr_T)nr_lines , nr_lines, true); /* Set '[ mark. */ curbuf->b_op_start = curwin->w_cursor; diff --git a/test/functional/lua/buffer_updates_spec.lua b/test/functional/lua/buffer_updates_spec.lua index 439cc12192..fa31880782 100644 --- a/test/functional/lua/buffer_updates_spec.lua +++ b/test/functional/lua/buffer_updates_spec.lua @@ -245,6 +245,31 @@ describe('lua buffer event callbacks: on_lines', function() helpers.assert_alive() end) + it('#12718 lnume', function() + meths.buf_set_lines(0, 0, -1, true, {'1', '2', '3'}) + exec_lua([[ + vim.api.nvim_buf_attach(0, false, { + on_lines = function(...) + vim.api.nvim_set_var('linesev', { ... }) + end, + }) + ]]) + feed('1G0') + feed('y<C-v>2j') + feed('G0') + feed('p') + -- Is the last arg old_byte_size correct? Doesn't matter for this PR + eq(meths.get_var('linesev'), { "lines", 1, 4, 2, 3, 5, 4 }) + + feed('2G0') + feed('p') + eq(meths.get_var('linesev'), { "lines", 1, 5, 1, 4, 4, 8 }) + + feed('1G0') + feed('P') + eq(meths.get_var('linesev'), { "lines", 1, 6, 0, 3, 3, 9 }) + + end) end) describe('lua: nvim_buf_attach on_bytes', function() @@ -452,6 +477,36 @@ describe('lua: nvim_buf_attach on_bytes', function() { "test1", "bytes", 1, 5, 0, 0, 0, 0, 0, 0, 0, 3, 3 }; } end) + + it('blockwise paste', function() + local check_events = setup_eventcheck(verify, {'1', '2', '3'}) + feed('1G0') + feed('y<C-v>2j') + feed('G0') + feed('p') + check_events { + { "test1", "bytes", 1, 3, 2, 1, 5, 0, 0, 0, 0, 1, 1 }; + { "test1", "bytes", 1, 3, 3, 0, 7, 0, 0, 0, 0, 3, 3 }; + { "test1", "bytes", 1, 3, 4, 0, 10, 0, 0, 0, 0, 3, 3 }; + } + + feed('2G0') + feed('p') + check_events { + { "test1", "bytes", 1, 4, 1, 1, 3, 0, 0, 0, 0, 1, 1 }; + { "test1", "bytes", 1, 4, 2, 1, 6, 0, 0, 0, 0, 1, 1 }; + { "test1", "bytes", 1, 4, 3, 1, 10, 0, 0, 0, 0, 1, 1 }; + } + + feed('1G0') + feed('P') + check_events { + { "test1", "bytes", 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 1 }; + { "test1", "bytes", 1, 5, 1, 0, 3, 0, 0, 0, 0, 1, 1 }; + { "test1", "bytes", 1, 5, 2, 0, 7, 0, 0, 0, 0, 1, 1 }; + } + + end) end describe('(with verify) handles', function() |