]> granicus.if.org Git - vim/commitdiff
patch 7.4.753 v7.4.753
authorBram Moolenaar <Bram@vim.org>
Thu, 25 Jun 2015 11:30:46 +0000 (13:30 +0200)
committerBram Moolenaar <Bram@vim.org>
Thu, 25 Jun 2015 11:30:46 +0000 (13:30 +0200)
Problem:    Appending in Visual mode with 'linebreak' set does not work
            properly.  Also when 'selection' is "exclusive". (Ingo Karkat)
Solution:   Recalculate virtual columns. (Christian Brabandt)

src/normal.c
src/testdir/test_listlbr.in
src/testdir/test_listlbr.ok
src/testdir/test_listlbr_utf8.in
src/testdir/test_listlbr_utf8.ok
src/version.c

index dc223c2ae417f0f9a6159bd4ba9c007112d7391d..9c9537f4b04172ef7cec047c1c8e78e26e93402b 100644 (file)
@@ -174,6 +174,7 @@ static void nv_drop __ARGS((cmdarg_T *cap));
 #ifdef FEAT_AUTOCMD
 static void    nv_cursorhold __ARGS((cmdarg_T *cap));
 #endif
+static void    get_op_vcol __ARGS((oparg_T *oap, colnr_T col, int initial));
 
 static char *e_noident = N_("E349: No identifier under cursor");
 
@@ -1418,6 +1419,8 @@ do_pending_operator(cap, old_col, gui_yank)
     {
 #ifdef FEAT_LINEBREAK
        /* Avoid a problem with unwanted linebreaks in block mode. */
+       if (curwin->w_p_lbr)
+           curwin->w_valid &= ~VALID_VIRTCOL;
        curwin->w_p_lbr = FALSE;
 #endif
        oap->is_VIsual = VIsual_active;
@@ -1631,61 +1634,7 @@ do_pending_operator(cap, old_col, gui_yank)
 
        if (VIsual_active || redo_VIsual_busy)
        {
-           if (VIsual_mode == Ctrl_V)  /* block mode */
-           {
-               colnr_T     start, end;
-
-               oap->block_mode = TRUE;
-
-               getvvcol(curwin, &(oap->start),
-                                     &oap->start_vcol, NULL, &oap->end_vcol);
-               if (!redo_VIsual_busy)
-               {
-                   getvvcol(curwin, &(oap->end), &start, NULL, &end);
-
-                   if (start < oap->start_vcol)
-                       oap->start_vcol = start;
-                   if (end > oap->end_vcol)
-                   {
-                       if (*p_sel == 'e' && start >= 1
-                                               && start - 1 >= oap->end_vcol)
-                           oap->end_vcol = start - 1;
-                       else
-                           oap->end_vcol = end;
-                   }
-               }
-
-               /* if '$' was used, get oap->end_vcol from longest line */
-               if (curwin->w_curswant == MAXCOL)
-               {
-                   curwin->w_cursor.col = MAXCOL;
-                   oap->end_vcol = 0;
-                   for (curwin->w_cursor.lnum = oap->start.lnum;
-                           curwin->w_cursor.lnum <= oap->end.lnum;
-                                                     ++curwin->w_cursor.lnum)
-                   {
-                       getvvcol(curwin, &curwin->w_cursor, NULL, NULL, &end);
-                       if (end > oap->end_vcol)
-                           oap->end_vcol = end;
-                   }
-               }
-               else if (redo_VIsual_busy)
-                   oap->end_vcol = oap->start_vcol + redo_VIsual_vcol - 1;
-               /*
-                * Correct oap->end.col and oap->start.col to be the
-                * upper-left and lower-right corner of the block area.
-                *
-                * (Actually, this does convert column positions into character
-                * positions)
-                */
-               curwin->w_cursor.lnum = oap->end.lnum;
-               coladvance(oap->end_vcol);
-               oap->end = curwin->w_cursor;
-
-               curwin->w_cursor = oap->start;
-               coladvance(oap->start_vcol);
-               oap->start = curwin->w_cursor;
-           }
+           get_op_vcol(oap, redo_VIsual_vcol, TRUE);
 
            if (!redo_VIsual_busy && !gui_yank)
            {
@@ -1982,7 +1931,11 @@ do_pending_operator(cap, old_col, gui_yank)
 #ifdef FEAT_LINEBREAK
                /* Restore linebreak, so that when the user edits it looks as
                 * before. */
-               curwin->w_p_lbr = lbr_saved;
+               if (curwin->w_p_lbr != lbr_saved)
+               {
+                   curwin->w_p_lbr = lbr_saved;
+                   get_op_vcol(oap, redo_VIsual_mode, FALSE);
+               }
 #endif
                /* Reset finish_op now, don't want it set inside edit(). */
                finish_op = FALSE;
@@ -2082,7 +2035,11 @@ do_pending_operator(cap, old_col, gui_yank)
 #ifdef FEAT_LINEBREAK
                /* Restore linebreak, so that when the user edits it looks as
                 * before. */
-               curwin->w_p_lbr = lbr_saved;
+               if (curwin->w_p_lbr != lbr_saved)
+               {
+                   curwin->w_p_lbr = lbr_saved;
+                   get_op_vcol(oap, redo_VIsual_mode, FALSE);
+               }
 #endif
                op_insert(oap, cap->count1);
 #ifdef FEAT_LINEBREAK
@@ -2114,11 +2071,15 @@ do_pending_operator(cap, old_col, gui_yank)
 #ifdef FEAT_VISUALEXTRA
            else
            {
-#ifdef FEAT_LINEBREAK
+# ifdef FEAT_LINEBREAK
                /* Restore linebreak, so that when the user edits it looks as
                 * before. */
-               curwin->w_p_lbr = lbr_saved;
-#endif
+               if (curwin->w_p_lbr != lbr_saved)
+               {
+                   curwin->w_p_lbr = lbr_saved;
+                   get_op_vcol(oap, redo_VIsual_mode, FALSE);
+               }
+# endif
                op_replace(oap, cap->nchar);
            }
 #endif
@@ -9542,3 +9503,70 @@ nv_cursorhold(cap)
     cap->retval |= CA_COMMAND_BUSY;    /* don't call edit() now */
 }
 #endif
+
+/*
+ * calculate start/end virtual columns for operating in block mode
+ */
+    static void
+get_op_vcol(oap, redo_VIsual_vcol, initial)
+    oparg_T    *oap;
+    colnr_T    redo_VIsual_vcol;
+    int                initial;            /* when true: adjust position for 'selectmode' */
+{
+    colnr_T        start, end;
+
+    if (VIsual_mode != Ctrl_V)
+       return;
+
+    oap->block_mode = TRUE;
+
+#ifdef FEAT_MBYTE
+    /* prevent from moving onto a trail byte */
+    if (has_mbyte)
+       mb_adjustpos(curwin->w_buffer, &oap->end);
+#endif
+
+    getvvcol(curwin, &(oap->start), &oap->start_vcol, NULL, &oap->end_vcol);
+    getvvcol(curwin, &(oap->end), &start, NULL, &end);
+
+    if (start < oap->start_vcol)
+       oap->start_vcol = start;
+    if (end > oap->end_vcol)
+    {
+       if (initial && *p_sel == 'e' && start >= 1
+                       && start - 1 >= oap->end_vcol)
+           oap->end_vcol = start - 1;
+       else
+           oap->end_vcol = end;
+    }
+    /* if '$' was used, get oap->end_vcol from longest line */
+    if (curwin->w_curswant == MAXCOL)
+    {
+       curwin->w_cursor.col = MAXCOL;
+       oap->end_vcol = 0;
+       for (curwin->w_cursor.lnum = oap->start.lnum;
+               curwin->w_cursor.lnum <= oap->end.lnum;
+                                       ++curwin->w_cursor.lnum)
+       {
+           getvvcol(curwin, &curwin->w_cursor, NULL, NULL, &end);
+           if (end > oap->end_vcol)
+               oap->end_vcol = end;
+       }
+    }
+    else if (redo_VIsual_busy)
+       oap->end_vcol = oap->start_vcol + redo_VIsual_vcol - 1;
+    /*
+    * Correct oap->end.col and oap->start.col to be the
+    * upper-left and lower-right corner of the block area.
+    *
+    * (Actually, this does convert column positions into character
+    * positions)
+    */
+    curwin->w_cursor.lnum = oap->end.lnum;
+    coladvance(oap->end_vcol);
+    oap->end = curwin->w_cursor;
+
+    curwin->w_cursor = oap->start;
+    coladvance(oap->start_vcol);
+    oap->start = curwin->w_cursor;
+}
index f6618c5a42e93911945af23a643d5700de33ae38..6af48a75e112d9849645029ca11383af0f3b9cd1 100644 (file)
@@ -59,11 +59,21 @@ STARTTEST
 :set cpo&vim linebreak
 :let g:test ="Test 6: set linebreak with visual block mode"
 :let line="REMOVE: this not"
+:$put =g:test
 :$put =line
 :let line="REMOVE: aaaaaaaaaaaaa"
 :$put =line
 :1/^REMOVE:
 0\16jf x:$put
+:set cpo&vim linebreak
+:let g:test ="Test 7: set linebreak with visual block mode and v_b_A"
+:$put =g:test
+Golong line: \e40afoobar \eaTARGET at end\e
+:exe "norm! $3B\<C-v>eAx\<Esc>"
+:set cpo&vim linebreak sbr=
+:let g:test ="Test 8: set linebreak with visual char mode and changing block"
+:$put =g:test
+Go1111-1111-1111-11-1111-1111-1111\e0f-lv3lc2222\ebgj.
 :%w! test.out
 :qa!
 ENDTEST
index ee74667661aa50701f9416afac397139cbba1657..82881234c4eb53167f65c422f045561b96e24470 100644 (file)
@@ -32,7 +32,12 @@ Sabbbbbb bla
 ~                   
 ~                   
 ~                   
+Test 6: set linebreak with visual block mode
 this not
 aaaaaaaaaaaaa
 REMOVE: 
 REMOVE: 
+Test 7: set linebreak with visual block mode and v_b_A
+long line: foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar TARGETx at end
+Test 8: set linebreak with visual char mode and changing block
+1111-2222-1111-11-1111-2222-1111
index 7448142a6d0024a46fd2df2e6de78e5a72ae94b7..61bb8a71b38dce9861c52d964774b4925f3ee820 100644 (file)
@@ -91,6 +91,11 @@ GGlGGlGGlGGlGGlGGlGGlGGlGGlGGl
 :else
 :   call append('$', "Not all attributes are different")
 :endif
+:set cpo&vim linebreak selection=exclusive
+:let g:test ="Test 8: set linebreak with visual block mode and v_b_A and selection=exclusive and multibyte char"
+:$put =g:test
+Golong line: \e40afoobar \eaTARGETÃ' at end\e
+:exe "norm! $3B\<C-v>eAx\<Esc>"
 :%w! test.out
 :qa!
 ENDTEST
index 5bd35bdecc0f791534f08ac3db0631276c6bb84d..25316c7531e8ed612a6f75894345bac9356b546c 100644 (file)
@@ -44,3 +44,5 @@ Test 6: Screenattributes for comment
  /*             and some more */
 ScreenAttributes for test6:
 Attribut 0 and 1 and 3 and 5 are different!
+Test 8: set linebreak with visual block mode and v_b_A and selection=exclusive and multibyte char
+long line: foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar TARGETÃx' at end
index 5a7e5ba3851a6b2e7e87e36744970b2976817b6a..c8eda423945eed78ee934d6e81b938e4036478ef 100644 (file)
@@ -741,6 +741,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    753,
 /**/
     752,
 /**/