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

Raspunde prin e-mail lui