aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKunMing Xie <qqzz014@gmail.com>2018-03-04 22:53:50 +0800
committerJustin M. Keyes <justinkz@gmail.com>2018-03-04 15:53:50 +0100
commit544cef0155ecb006c34e8471733cac6bdfd61989 (patch)
treeb44ca629912725c80bac9a120cc64f3b4e165567
parentb22d3385b986ee6922298c019a4f3976d37897cc (diff)
downloadrneovim-544cef0155ecb006c34e8471733cac6bdfd61989.tar.gz
rneovim-544cef0155ecb006c34e8471733cac6bdfd61989.tar.bz2
rneovim-544cef0155ecb006c34e8471733cac6bdfd61989.zip
vim-patch:8.0.0234,8.0.0236,8.0.0225 (#8052)
vim-patch:8.0.0234: crash when using put in Visual mode Problem: When several lines are visually selected and one of them is short, using put may cause a crash. (Axel Bender) Solution: Check for a short line. (Christian Brabandt) https://github.com/vim/vim/commit/941c12da3c087fd04aa6c120a76bf28f19349d96 vim-patch:8.0.0236: gcc complains about uninitialized variable Problem: Gcc complains that a variable may be used uninitialized. Confusion between variable and label name. (John Marriott) Solution: Initialize it. Rename end to end_lnum. https://github.com/vim/vim/commit/6a717f17ec6b09634be1c29e0ac4c35213f7b32d vim-patch:8.0.0225: put in Visual block mode terminates early Problem: When a block is visually selected and put is used on the end of the selection only one line is changed. Solution: Check for the end properly. (Christian Brabandt, neovim issue 5781) https://github.com/vim/vim/commit/9957a10d0f0c34d8083af6ed66e198e4796038e0
-rw-r--r--src/nvim/ops.c26
-rw-r--r--src/nvim/testdir/test_put.vim13
2 files changed, 31 insertions, 8 deletions
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index 4d974f5760..b421d81b7e 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -3078,15 +3078,26 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
--lnum;
new_cursor = curwin->w_cursor;
- /*
- * simple case: insert into current line
- */
+ // simple case: insert into current line
if (y_type == kMTCharWise && y_size == 1) {
+ linenr_T end_lnum = 0; // init for gcc
+
+ if (VIsual_active) {
+ end_lnum = curbuf->b_visual.vi_end.lnum;
+ if (end_lnum < curbuf->b_visual.vi_start.lnum) {
+ end_lnum = curbuf->b_visual.vi_start.lnum;
+ }
+ }
+
do {
totlen = (size_t)(count * yanklen);
if (totlen > 0) {
oldp = ml_get(lnum);
- newp = (char_u *) xmalloc((size_t)(STRLEN(oldp) + totlen + 1));
+ if (VIsual_active && col > (int)STRLEN(oldp)) {
+ lnum++;
+ continue;
+ }
+ newp = (char_u *)xmalloc((size_t)(STRLEN(oldp) + totlen + 1));
memmove(newp, oldp, (size_t)col);
ptr = newp + col;
for (i = 0; i < (size_t)count; i++) {
@@ -3102,11 +3113,10 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
curwin->w_cursor.col += (colnr_T)(totlen - 1);
}
}
- if (VIsual_active)
+ if (VIsual_active) {
lnum++;
- } while (VIsual_active
- && (lnum <= curbuf->b_visual.vi_end.lnum
- || lnum <= curbuf->b_visual.vi_start.lnum));
+ }
+ } while (VIsual_active && lnum <= end_lnum);
if (VIsual_active) { /* reset lnum to the last visual line */
lnum--;
diff --git a/src/nvim/testdir/test_put.vim b/src/nvim/testdir/test_put.vim
index 0154de1ec0..38c812bc9c 100644
--- a/src/nvim/testdir/test_put.vim
+++ b/src/nvim/testdir/test_put.vim
@@ -21,3 +21,16 @@ func Test_put_char_block()
call assert_equal(['Xfile_put 1', 'Xfile_put 2'], getline(1,2))
bw!
endfunc
+
+func Test_put_char_block2()
+ new
+ let a = [ getreg('a'), getregtype('a') ]
+ call setreg('a', ' one ', 'v')
+ call setline(1, ['Line 1', '', 'Line 3', ''])
+ " visually select the first 3 lines and put register a over it
+ exe "norm! ggl\<c-v>2j2l\"ap"
+ call assert_equal(['L one 1', '', 'L one 3', ''], getline(1,4))
+ " clean up
+ bw!
+ call setreg('a', a[0], a[1])
+endfunc