Bram, attached patch fixes a bug in visual paste when the cursor is on the other side of a visually selected region, because the abort condition of the do() while loop assumes b_visual.vi_end.lnum will be the last visually selected line.
This is however not true, if 'o' in visual mode has been used and so it will terminate the loop too early. So here is a patch that fixes the issue and also adds a test. This issue was reported at neovim/neovim#5781 Best, Christian -- -- You received this message from the "vim_dev" maillist. Do not top-post! Type your reply below the text you are replying to. For more information, visit http://www.vim.org/maillist.php --- You received this message because you are subscribed to the Google Groups "vim_dev" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
From 769fbb2d483eacc606de4ed3465bba5e8211c743 Mon Sep 17 00:00:00 2001 From: Christian Brabandt <[email protected]> Date: Mon, 23 Jan 2017 21:05:39 +0100 Subject: [PATCH] put charwise over complete range When putting a charwise register over a visually selected region and the cursor is "on the other side" of the visual selection (e.g. "o" has been used), Vim will only put over the first selected line and abort and not run over the complete selection. this is because in that case curbuf->b_visual.vi_start.lnum is actually the last selected line while vi_end.lnum is the first selected line, so this will abort the do() while loop in do_put too early. Fix this, by corectly setting the end condition. Also add a test to correctly verify the behaviour reported at neovim/neovim#5781 --- src/ops.c | 7 ++++++- src/testdir/test_put.vim | 11 +++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/ops.c b/src/ops.c index 4d01ef1c6..1abb8daa1 100644 --- a/src/ops.c +++ b/src/ops.c @@ -3774,6 +3774,11 @@ do_put( */ if (y_type == MCHAR && y_size == 1) { + linenr_T end = curbuf->b_visual.vi_end.lnum; + + if (curbuf->b_visual.vi_end.lnum < curbuf->b_visual.vi_start.lnum) + end = curbuf->b_visual.vi_start.lnum; + do { totlen = count * yanklen; if (totlen > 0) @@ -3801,7 +3806,7 @@ do_put( } if (VIsual_active) lnum++; - } while (VIsual_active && lnum <= curbuf->b_visual.vi_end.lnum); + } while (VIsual_active && lnum <= end); if (VIsual_active) /* reset lnum to the last visual line */ lnum--; diff --git a/src/testdir/test_put.vim b/src/testdir/test_put.vim index 612bdabb6..0154de1ec 100644 --- a/src/testdir/test_put.vim +++ b/src/testdir/test_put.vim @@ -10,3 +10,14 @@ func Test_put_block() call assert_equal("\u2500x", getline(1)) bwipe! endfunc + +func Test_put_char_block() + new + call setline(1, ['Line 1', 'Line 2']) + f Xfile_put + " visually select both lines and put the cursor at the top of the visual + " selection and then put the buffer name over it + exe "norm! G0\<c-v>ke\"%p" + call assert_equal(['Xfile_put 1', 'Xfile_put 2'], getline(1,2)) + bw! +endfunc -- 2.11.0
