Bram,
here is a patch for an obscure bug when block-inserting.
While I was trying to fix another thing I noticed that Vim wouldn't let 
me block insert a tab char in front of a block selection.

The problem is, when there are spaces in front of the visually selected 
block and you are inserting tabs, the spaces in front of the block might
be changed to a single tab (according to your sts and ts settings) and 
therefore the oap->start position will be wrong.

(It took me a while until I figured out, that the column position 
actually decreases although I have added a single char. That was really 
unexpected).

This will finally lead to the situation that Vim thinks, the length of 
the inserted text is negative and abort. So here is a patch, that fixes 
this and also includes a test. 

(Test suite successful run 
https://travis-ci.org/chrisbra/vim-ci/builds/48824000)

Best,
Christian
-- 
Daß Frauen bisweilen boshafter sein können als Männer, mag daran
lieben, daß die Erbsünde zuerst in sie gefahren ist.
                -- Ernst R. Hauschka

-- 
-- 
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.
diff --git a/src/ops.c b/src/ops.c
--- a/src/ops.c
+++ b/src/ops.c
@@ -2544,6 +2544,7 @@ op_insert(oap, count1)
     char_u		*firstline, *ins_text;
     struct block_def	bd;
     int			i;
+    pos_T		t1;
 
     /* edit() changes this - record it for OP_APPEND */
     bd.is_MAX = (curwin->w_curswant == MAXCOL);
@@ -2617,7 +2618,14 @@ op_insert(oap, count1)
 	}
     }
 
+    t1 = oap->start;
     edit(NUL, FALSE, (linenr_T)count1);
+    /* when a tab was inserted, and the characters in front of the tab
+     * have been converted to a tab as well, the column of the cursor
+     * might have actually been reduced, so need to adjust here */
+    if (t1.lnum == curbuf->b_op_start_orig.lnum
+	    && lt(curbuf->b_op_start_orig, t1))
+	oap->start = curbuf->b_op_start_orig;
 
     /* If user has moved off this line, we don't know what to do, so do
      * nothing.
@@ -2644,10 +2652,10 @@ op_insert(oap, count1)
 #endif
 			)
 	    {
+		int t = getviscol2(curbuf->b_op_start_orig.col, curbuf->b_op_start_orig.coladd);
 		oap->start.col = curbuf->b_op_start_orig.col;
-		pre_textlen -= getviscol2(oap->start.col, oap->start.coladd)
-							    - oap->start_vcol;
-		oap->start_vcol = getviscol2(oap->start.col, oap->start.coladd);
+		pre_textlen -= t - oap->start_vcol;
+		oap->start_vcol = t;
 	    }
 	    else if (oap->op_type == OP_APPEND
 		      && oap->end.col
@@ -2660,12 +2668,12 @@ op_insert(oap, count1)
 #endif
 			)
 	    {
+		int t = getviscol2(curbuf->b_op_start_orig.col, curbuf->b_op_start_orig.coladd);
 		oap->start.col = curbuf->b_op_start_orig.col;
 		/* reset pre_textlen to the value of OP_INSERT */
 		pre_textlen += bd.textlen;
-		pre_textlen -= getviscol2(oap->start.col, oap->start.coladd)
-							    - oap->start_vcol;
-		oap->start_vcol = getviscol2(oap->start.col, oap->start.coladd);
+		pre_textlen -= t - oap->start_vcol;
+		oap->start_vcol = t;
 		oap->op_type = OP_INSERT;
 	    }
 	}
diff --git a/src/testdir/test39.in b/src/testdir/test39.in
--- a/src/testdir/test39.in
+++ b/src/testdir/test39.in
@@ -2,6 +2,10 @@
 Test Visual block mode commands
 And test "U" in Visual mode, also on German sharp S.
 
+#define BO_ALL	    0x0001
+#define BO_BS	    0x0002
+#define BO_CRSR	    0x0004
+
 STARTTEST
 :so small.vim
 :so mbyte.vim
@@ -70,6 +74,12 @@ G3o987652k02l2jr
 :exe ":norm! 2k\<C-V>$gj\<Esc>"
 :let cpos=getpos("'>")
 :$put ='col:'.cpos[2].' off:'.cpos[3]
+:"
+:" block_insert when replacing spaces in front of the block with tabs
+:set ts=8 sts=4 sw=4
+:4,7y
+Gp
+:exe ":norm! f0\<C-V>2jI\<tab>\<esc>"
 :/^the/,$w >> test.out
 :qa!
 ENDTEST
diff --git a/src/testdir/test39.ok b/src/testdir/test39.ok
index 5c517e2223d5c830ca8297b7c8ec71d180777d82..349d67fe775b797974d039d14e918edecdee245f
GIT binary patch
literal 662
zc$|e&+iHVA5bdi2{fB`*2Xt3+qZBj>DM*E=&^{H{OOn=T3l+3K+h6IpN!pEAx)0~<
zoO5P&7dC0TPmyMMvEA)oUdsa{B)ro?#6wkUDA&-;i{3>1%iWSI6&l?uCqGFL2|x&e
zNC0V?A`(EBWrzd-w{LfCpCJ}~ggEUJ#F-4(j3)w2YdRwWhjCQO)!9tM4B&LX7PWF;
z<;I|9gPJQ1XB_mYG8>m^%EvCpry!2vF!bUW^D2W0b^(=AdTek4(b`ip-h&H<VT`Db
zZ?Dn42R9&!BVdg6^Sk;Y#X0}!{mPq09%?XdS}>b0Mt6((_0+n+|MFKd`HN{?E={b9
nVyOe%&>y1bqZ2&azOQL|tLwU<%1$VM)6rq7v)Y6k#WUd>U9zd>

Raspunde prin e-mail lui