aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/ops.c9
-rw-r--r--test/functional/lua/buffer_updates_spec.lua55
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()