]> granicus.if.org Git - vim/commitdiff
updated for version 7.2-137 v7.2.137
authorBram Moolenaar <Bram@vim.org>
Wed, 11 Mar 2009 15:28:26 +0000 (15:28 +0000)
committerBram Moolenaar <Bram@vim.org>
Wed, 11 Mar 2009 15:28:26 +0000 (15:28 +0000)
src/ops.c
src/testdir/Makefile
src/testdir/test66.in [new file with mode: 0644]
src/testdir/test66.ok [new file with mode: 0644]
src/version.c

index 557985c38ad1a7eaaf8849d5fd102727ecc916a0..b60fca3ea3dd8bd6ffc3e1fbd55aae842564cc80 100644 (file)
--- a/src/ops.c
+++ b/src/ops.c
@@ -72,11 +72,11 @@ static struct yankreg       *y_previous = NULL; /* ptr to last written yankreg */
  */
 struct block_def
 {
-    int                startspaces;    /* 'extra' cols of first char */
-    int                endspaces;      /* 'extra' cols of first char */
+    int                startspaces;    /* 'extra' cols before first char */
+    int                endspaces;      /* 'extra' cols after last char */
     int                textlen;        /* chars in block */
-    char_u     *textstart;     /* pointer to 1st char in block */
-    colnr_T    textcol;        /* cols of chars (at least part.) in block */
+    char_u     *textstart;     /* pointer to 1st char (partially) in block */
+    colnr_T    textcol;        /* index of chars (partially) in block */
     colnr_T    start_vcol;     /* start col of 1st char wholly inside block */
     colnr_T    end_vcol;       /* start col of 1st char wholly after block */
 #ifdef FEAT_VISUALEXTRA
@@ -382,15 +382,14 @@ shift_block(oap, amount)
 {
     int                        left = (oap->op_type == OP_LSHIFT);
     int                        oldstate = State;
-    int                        total, split;
-    char_u             *newp, *oldp, *midp, *ptr;
+    int                        total;
+    char_u             *newp, *oldp;
     int                        oldcol = curwin->w_cursor.col;
     int                        p_sw = (int)curbuf->b_p_sw;
     int                        p_ts = (int)curbuf->b_p_ts;
     struct block_def   bd;
-    int                        internal = 0;
     int                        incr;
-    colnr_T            vcol, col = 0, ws_vcol;
+    colnr_T            ws_vcol;
     int                        i = 0, j = 0;
     int                        len;
 
@@ -456,67 +455,89 @@ shift_block(oap, amount)
     }
     else /* left */
     {
-       vcol = oap->start_vcol;
-       /* walk vcol past ws to be removed */
-       for (midp = oldp + bd.textcol;
-             vcol < (oap->start_vcol + total) && vim_iswhite(*midp); )
-       {
-           incr = lbr_chartabsize_adv(&midp, (colnr_T)vcol);
-           vcol += incr;
-       }
-       /* internal is the block-internal ws replacing a split TAB */
-       if (vcol > (oap->start_vcol + total))
-       {
-           /* we have to split the TAB *(midp-1) */
-           internal = vcol - (oap->start_vcol + total);
-       }
-       /* if 'expandtab' is not set, use TABs */
+       colnr_T     destination_col;    /* column to which text in block will
+                                          be shifted */
+       char_u      *verbatim_copy_end; /* end of the part of the line which is
+                                          copied verbatim */
+       colnr_T     verbatim_copy_width;/* the (displayed) width of this part
+                                          of line */
+       unsigned    fill;               /* nr of spaces that replace a TAB */
+       unsigned    new_line_len;       /* the length of the line after the
+                                          block shift */
+       size_t      block_space_width;
+       size_t      shift_amount;
+       char_u      *non_white = bd.textstart;
+       colnr_T     non_white_col;
 
-       split = bd.startspaces + internal;
-       if (split > 0)
-       {
-           if (!curbuf->b_p_et)
-           {
-               for (ptr = oldp, col = 0; ptr < oldp+bd.textcol; )
-                   col += lbr_chartabsize_adv(&ptr, (colnr_T)col);
+       /*
+        * Firstly, let's find the first non-whitespace character that is
+        * displayed after the block's start column and the character's column
+        * number. Also, let's calculate the width of all the whitespace
+        * characters that are displayed in the block and precede the searched
+        * non-whitespace character.
+        */
 
-               /* col+1 now equals the start col of the first char of the
-                * block (may be < oap.start_vcol if we're splitting a TAB) */
-               i = ((col % p_ts) + split) / p_ts; /* number of tabs */
-           }
-           if (i)
-               j = ((col % p_ts) + split) % p_ts; /* number of spp */
-           else
-               j = split;
-       }
+       /* If "bd.startspaces" is set, "bd.textstart" points to the character,
+        * the part of which is displayed at the block's beginning. Let's start
+        * searching from the next character. */
+       if (bd.startspaces)
+           mb_ptr_adv(non_white);
 
-       newp = alloc_check(bd.textcol + i + j + (unsigned)STRLEN(midp) + 1);
-       if (newp == NULL)
-           return;
-       vim_memset(newp, NUL, (size_t)(bd.textcol + i + j + STRLEN(midp) + 1));
+       /* The character's column is in "bd.start_vcol".  */
+       non_white_col = bd.start_vcol;
 
-       /* copy first part we want to keep */
-       mch_memmove(newp, oldp, (size_t)bd.textcol);
-       /* Now copy any TABS and spp to ensure correct alignment! */
-       while (vim_iswhite(*midp))
+       while (vim_iswhite(*non_white))
        {
-           if (*midp == TAB)
-               i++;
-           else /*space */
-               j++;
-           midp++;
+           incr = lbr_chartabsize_adv(&non_white, non_white_col);
+           non_white_col += incr;
        }
-       /* We might have an extra TAB worth of spp now! */
-       if (j / p_ts && !curbuf->b_p_et)
+
+       block_space_width = non_white_col - oap->start_vcol;
+       /* We will shift by "total" or "block_space_width", whichever is less.
+        */
+       shift_amount = (block_space_width < total? block_space_width: total);
+
+       /* The column to which we will shift the text.  */
+       destination_col = non_white_col - shift_amount;
+
+       /* Now let's find out how much of the beginning of the line we can
+        * reuse without modification.  */
+       verbatim_copy_end = bd.textstart;
+       verbatim_copy_width = bd.start_vcol;
+
+       /* If "bd.startspaces" is set, "bd.textstart" points to the character
+        * preceding the block. We have to subtract its width to obtain its
+        * column number.  */
+       if (bd.startspaces)
+           verbatim_copy_width -= bd.start_char_vcols;
+       while (verbatim_copy_width < destination_col)
        {
-           i++;
-           j -= p_ts;
+           incr = lbr_chartabsize(verbatim_copy_end, verbatim_copy_width);
+           if (verbatim_copy_width + incr > destination_col)
+               break;
+           verbatim_copy_width += incr;
+           mb_ptr_adv(verbatim_copy_end);
        }
-       copy_chars(newp + bd.textcol, (size_t)i, TAB);
-       copy_spaces(newp + bd.textcol + i, (size_t)j);
 
-       /* the end */
-       STRMOVE(newp + STRLEN(newp), midp);
+       /* If "destination_col" is different from the width of the initial
+        * part of the line that will be copied, it means we encountered a tab
+        * character, which we will have to partly replace with spaces.  */
+       fill = destination_col - verbatim_copy_width;
+
+       /* The replacement line will consist of:
+        * - the beginning of the original line up to "verbatim_copy_end",
+        * - "fill" number of spaces,
+        * - the rest of the line, pointed to by non_white.  */
+       new_line_len = (unsigned)(verbatim_copy_end - oldp)
+                      + fill
+                      + (unsigned)STRLEN(non_white) + 1;
+
+       newp = alloc_check(new_line_len);
+       if (newp == NULL)
+           return;
+       mch_memmove(newp, oldp, (size_t)(verbatim_copy_end - oldp));
+       copy_spaces(newp + (verbatim_copy_end - oldp), (size_t)fill);
+       STRMOVE(newp + (verbatim_copy_end - oldp) + fill, non_white);
     }
     /* replace the line */
     ml_replace(curwin->w_cursor.lnum, newp, FALSE);
@@ -4851,7 +4872,8 @@ paragraph_start(lnum)
  * - textlen includes the first/last char to be (partly) deleted
  * - start/endspaces is the number of columns that are taken by the
  *   first/last deleted char minus the number of columns that have to be
- *   deleted.  for yank and tilde:
+ *   deleted.
+ * for yank and tilde:
  * - textlen includes the first/last char to be wholly yanked
  * - start/endspaces is the number of columns of the first/last yanked char
  *   that are to be yanked.
index 3528bf6f3f824c8f69b9f7cff7e6381b322da8b3..b60bd4885a1d0ea9b3db7fbeb2dadb71f7b95474 100644 (file)
@@ -20,7 +20,7 @@ SCRIPTS = test1.out test2.out test3.out test4.out test5.out test6.out \
                test48.out test49.out test51.out test52.out test53.out \
                test54.out test55.out test56.out test57.out test58.out \
                test59.out test60.out test61.out test62.out test63.out \
-               test64.out test65.out
+               test64.out test65.out test66.out
 
 SCRIPTS_GUI = test16.out
 
diff --git a/src/testdir/test66.in b/src/testdir/test66.in
new file mode 100644 (file)
index 0000000..113b540
--- /dev/null
@@ -0,0 +1,25 @@
+
+Test for visual block shift and tab characters.
+
+STARTTEST
+:so small.vim
+/^abcdefgh
+\164jI    \ej<<11|D
+7|a            \e
+7|a               \e
+7|a            \e4k13|\164j<
+:$-4,$w! test.out
+:$-4,$s/\s\+//g
+\164kI    \ej<<
+7|a            \e
+7|a                                    \e
+7|a                    \e4k13|\164j3<
+:$-4,$w >> test.out
+:qa!
+ENDTEST
+
+abcdefghijklmnopqrstuvwxyz
+abcdefghijklmnopqrstuvwxyz
+abcdefghijklmnopqrstuvwxyz
+abcdefghijklmnopqrstuvwxyz
+abcdefghijklmnopqrstuvwxyz
diff --git a/src/testdir/test66.ok b/src/testdir/test66.ok
new file mode 100644 (file)
index 0000000..2c2249b
--- /dev/null
@@ -0,0 +1,10 @@
+    abcdefghijklmnopqrstuvwxyz
+abcdefghij
+    abc            defghijklmnopqrstuvwxyz
+    abc            defghijklmnopqrstuvwxyz
+    abc            defghijklmnopqrstuvwxyz
+    abcdefghijklmnopqrstuvwxyz
+abcdefghij
+    abc            defghijklmnopqrstuvwxyz
+    abc                defghijklmnopqrstuvwxyz
+    abc            defghijklmnopqrstuvwxyz
index e9c7a677d7cce2b3467b611ce2d60262abeaba66..44f296dca0e465577bc89d6778c00120c72c1188 100644 (file)
@@ -676,6 +676,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    137,
 /**/
     136,
 /**/